diff --git a/Plugins/PluginList.cmake b/Plugins/PluginList.cmake index de27ac4b0d..67b5e41db5 100644 --- a/Plugins/PluginList.cmake +++ b/Plugins/PluginList.cmake @@ -1,40 +1,41 @@ # Plug-ins must be ordered according to their dependencies set(MITK_EXT_PLUGINS org.mitk.core.services:ON org.mitk.gui.common:ON org.mitk.planarfigure:ON org.mitk.core.ext:OFF org.mitk.core.jobs:OFF org.mitk.diffusionimaging:OFF org.mitk.gui.qt.application:ON org.mitk.gui.qt.coreapplication:OFF org.mitk.gui.qt.ext:OFF org.mitk.gui.qt.extapplication:OFF org.mitk.gui.qt.common:ON org.mitk.gui.qt.stdmultiwidgeteditor:ON org.mitk.gui.qt.common.legacy:OFF org.mitk.gui.qt.diffusionimagingapp:OFF org.mitk.gui.qt.datamanager:ON org.mitk.gui.qt.basicimageprocessing:OFF org.mitk.gui.qt.diffusionimaging:OFF org.mitk.gui.qt.dtiatlasapp:OFF org.mitk.gui.qt.examples:OFF org.mitk.gui.qt.examplesopencv:OFF org.mitk.gui.qt.igtexamples:OFF org.mitk.gui.qt.igttracking:OFF org.mitk.gui.qt.imagecropper:OFF org.mitk.gui.qt.imagenavigator:ON org.mitk.gui.qt.materialeditor:OFF org.mitk.gui.qt.measurementtoolbox:OFF + org.mitk.gui.qt.meshdecimation:OFF org.mitk.gui.qt.moviemaker:OFF org.mitk.gui.qt.pointsetinteraction:OFF org.mitk.gui.qt.python.console:OFF org.mitk.gui.qt.registration:OFF org.mitk.gui.qt.segmentation:OFF org.mitk.gui.qt.toftutorial:OFF org.mitk.gui.qt.tofutil:OFF org.mitk.gui.qt.ugvisualization:OFF org.mitk.gui.qt.volumevisualization:OFF -) \ No newline at end of file +) diff --git a/Plugins/org.mitk.gui.qt.meshdecimation/CMakeLists.txt b/Plugins/org.mitk.gui.qt.meshdecimation/CMakeLists.txt new file mode 100644 index 0000000000..514256f123 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.meshdecimation/CMakeLists.txt @@ -0,0 +1,8 @@ +PROJECT(org_mitk_gui_qt_meshdecimation) + +MACRO_CREATE_MITK_CTK_PLUGIN( + EXPORT_DIRECTIVE MESHDECIMATION_EXPORT + EXPORTED_INCLUDE_SUFFIXES src + MODULE_DEPENDENCIES QmitkExt +) + diff --git a/Plugins/org.mitk.gui.qt.meshdecimation/documentation/Manual/meshdecimation-manual.dox b/Plugins/org.mitk.gui.qt.meshdecimation/documentation/Manual/meshdecimation-manual.dox new file mode 100644 index 0000000000..33ead4ba4d --- /dev/null +++ b/Plugins/org.mitk.gui.qt.meshdecimation/documentation/Manual/meshdecimation-manual.dox @@ -0,0 +1,33 @@ +/** + +\bundlemainpage{org_meshdecimation} The Mesh Decimation Module + +\image html meshdecimation.png "Icon of the Module" + +Available sections: + - \ref meshdecimationOverview + - \ref meshdecimationFeatures + - \ref meshdecimationUsage + +\section meshdecimationOverview Overview + +MeshDecimation is a user friendly tool to decimate a MITK surface. + +\section meshdecimationFeatures Features + +The module offers two basic procedures to decimate surfaces: One that reduces a surface with a possible loss of topology (quality), but with a garuanteed reduction rate that is expressed in terms of percent of the original mesh. The other variant preserves the topology and stops decimating when it detects heavy topological changes. + +\section meshdecimationUsage Usage + +\image html meshdecimation-ui.png "The user interface of the Mesh Decimation Module" + +The usage of the module should be straightforward, as shown in the screenshot. To decimate a MITK surface do the following: +- Select a surface in the datamanager +- Enter a target reduction rate +- Select a decimation method (\ref meshdecimationFeatures) +- Press the "Decimate" button +- Repeat the process until you are satisfied with the decimation +- Save the surface to disk + +*/ + diff --git a/Plugins/org.mitk.gui.qt.meshdecimation/documentation/Manual/meshdecimation-ui.png b/Plugins/org.mitk.gui.qt.meshdecimation/documentation/Manual/meshdecimation-ui.png new file mode 100644 index 0000000000..97b45078fe Binary files /dev/null and b/Plugins/org.mitk.gui.qt.meshdecimation/documentation/Manual/meshdecimation-ui.png differ diff --git a/Plugins/org.mitk.gui.qt.meshdecimation/documentation/Manual/meshdecimation.png b/Plugins/org.mitk.gui.qt.meshdecimation/documentation/Manual/meshdecimation.png new file mode 100644 index 0000000000..8ba6124527 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.meshdecimation/documentation/Manual/meshdecimation.png differ diff --git a/Plugins/org.mitk.gui.qt.meshdecimation/documentation/doxygen/modules.dox b/Plugins/org.mitk.gui.qt.meshdecimation/documentation/doxygen/modules.dox new file mode 100644 index 0000000000..8c37f6ce32 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.meshdecimation/documentation/doxygen/modules.dox @@ -0,0 +1,8 @@ +/** + \defgroup org_mbi_gui_qt_meshdecimation org.mbi.gui.qt.meshdecimation Plugin + \ingroup MBIPlugins + + \brief The plugin is a user friendly tool to decimate a mesh. + + It has no public API and uses VTK filters internally to decimate MITK Surfaces. Please refer to the user manual for usage information. +*/ diff --git a/Plugins/org.mitk.gui.qt.meshdecimation/files.cmake b/Plugins/org.mitk.gui.qt.meshdecimation/files.cmake new file mode 100644 index 0000000000..6db717a8e8 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.meshdecimation/files.cmake @@ -0,0 +1,37 @@ +SET(SRC_CPP_FILES + +) + +SET(INTERNAL_CPP_FILES + QmitkMeshDecimationView.cpp + mitkPluginActivator.cpp +) + +SET(UI_FILES + src/internal/QmitkMeshDecimationView.ui +) + +SET(MOC_H_FILES + src/internal/QmitkMeshDecimationView.h + src/internal/mitkPluginActivator.h +) + +SET(CACHED_RESOURCE_FILES + resources/meshdecimation.png + plugin.xml +) + +SET(QRC_FILES + +) + +SET(CPP_FILES ) + +foreach(file ${SRC_CPP_FILES}) + SET(CPP_FILES ${CPP_FILES} src/${file}) +endforeach(file ${SRC_CPP_FILES}) + +foreach(file ${INTERNAL_CPP_FILES}) + SET(CPP_FILES ${CPP_FILES} src/internal/${file}) +endforeach(file ${INTERNAL_CPP_FILES}) + diff --git a/Plugins/org.mitk.gui.qt.meshdecimation/manifest_headers.cmake b/Plugins/org.mitk.gui.qt.meshdecimation/manifest_headers.cmake new file mode 100644 index 0000000000..824126c979 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.meshdecimation/manifest_headers.cmake @@ -0,0 +1,5 @@ +set(Plugin-Name "Mesh Decimation") +set(Plugin-Version "0.1") +set(Plugin-Vendor "DKFZ, Medical and Biological Informatics") +set(Plugin-ContactAddress "http://www.mitk.org") +set(Require-Plugin org.mitk.gui.qt.common) diff --git a/Plugins/org.mitk.gui.qt.meshdecimation/plugin.xml b/Plugins/org.mitk.gui.qt.meshdecimation/plugin.xml new file mode 100644 index 0000000000..13005afb6a --- /dev/null +++ b/Plugins/org.mitk.gui.qt.meshdecimation/plugin.xml @@ -0,0 +1,12 @@ + + + + + + + + + \ No newline at end of file diff --git a/Plugins/org.mitk.gui.qt.meshdecimation/resources/meshdecimation.png b/Plugins/org.mitk.gui.qt.meshdecimation/resources/meshdecimation.png new file mode 100644 index 0000000000..8ba6124527 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.meshdecimation/resources/meshdecimation.png differ diff --git a/Plugins/org.mitk.gui.qt.meshdecimation/src/internal/QmitkMeshDecimationView.cpp b/Plugins/org.mitk.gui.qt.meshdecimation/src/internal/QmitkMeshDecimationView.cpp new file mode 100644 index 0000000000..44d8642dac --- /dev/null +++ b/Plugins/org.mitk.gui.qt.meshdecimation/src/internal/QmitkMeshDecimationView.cpp @@ -0,0 +1,232 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Language: C++ +Date: $Date$ +Version: $Revision$ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +// Blueberry +#include +#include + +// Qmitk +#include "QmitkMeshDecimationView.h" +#include "QmitkStdMultiWidget.h" + +// Qt +#include +#include +#include + +// mitk +#include +#include +#include + +// VTK +#include +#include +#include + +const std::string QmitkMeshDecimationView::VIEW_ID = "org.mitk.views.meshdecimation"; + +QmitkMeshDecimationView::QmitkMeshDecimationView() +: QmitkAbstractView() +, m_Controls( 0 ) +, m_MessageBox( 0 ) +, m_MessageBoxDisplayTime( 5 ) +, m_MessageBoxTimer( new QTimer(this) ) +{ + m_MessageBoxTimer->setInterval(1000); + connect(m_MessageBoxTimer, SIGNAL(timeout()), this, SLOT(MessageBoxTimer())); +} + +QmitkMeshDecimationView::~QmitkMeshDecimationView() +{ +} + +void QmitkMeshDecimationView::CreateQtPartControl( QWidget *parent ) +{ + // build up qt view, unless already done + if ( !m_Controls ) + { + // create GUI widgets from the Qt Designer's .ui file + m_Controls = new Ui::QmitkMeshDecimationView; + m_Controls->setupUi( parent ); + + connect((QObject*)(m_Controls->Decimate), SIGNAL(clicked()), this, SLOT(Decimate())); + } +} + +void QmitkMeshDecimationView::OnSelectionChanged(berry::IWorkbenchPart::Pointer, const QList& nodes) +{ + this->m_Node = 0; + this->DisableGui(); + + for( int i=0; iGetData(); + if( dynamic_cast( baseData ) != 0 ) + { + this->m_Node = nodes.at(i); + this->m_Controls->NodeLabel->setEnabled( true ); + this->m_Controls->TargetReduction->setEnabled( true ); + this->m_Controls->Decimate->setEnabled( true ); + this->m_Controls->DecimationType->setEnabled( true ); + break; + } + } + this->UpdateNodeLabel(); +} + +void QmitkMeshDecimationView::SetFocus() +{ + m_Controls->NodeLabel->setFocus(); +} + +void QmitkMeshDecimationView::DisableGui() +{ + this->m_Controls->NodeLabel->setEnabled( false ); + this->m_Controls->TargetReduction->setEnabled( false ); + this->m_Controls->Decimate->setEnabled( false ); + this->m_Controls->DecimationType->setEnabled( false ); +} + +void QmitkMeshDecimationView::UpdateNodeLabel() +{ + QString nodeLabel = "none selected"; + if (this->m_Node.IsNotNull()) + { + vtkPolyData* polyData = static_cast(this->m_Node->GetData())->GetVtkPolyData(); + nodeLabel = QString::fromStdString( this->m_Node->GetName() ); + nodeLabel.append(" ("); + nodeLabel.append( QString("%1").arg( polyData->GetNumberOfCells() ) ); + nodeLabel.append(" cells)"); + } + this->m_Controls->NodeLabel->setText( nodeLabel ); +} + +void QmitkMeshDecimationView::Decimate() +{ + if (this->m_Node.IsNotNull()) + { + this->WaitCursorOn(); + QString error; + try + { + vtkPolyData* polyData = static_cast(this->m_Node->GetData())->GetVtkPolyData(); + int startingNumberOfCells = polyData->GetNumberOfCells(); + if( startingNumberOfCells == 0 ) + throw std::logic_error("Could not reduce Mesh since it is already empty."); + + + double targetReduction = static_cast(this->m_Controls->TargetReduction->value()) / 100.0; + + vtkPolyData* newPolyData = 0; + if( this->m_Controls->DecimationType->currentText() == "DecimatePro" ) + { + vtkSmartPointer decimator = vtkDecimatePro::New(); + decimator->SetInput( polyData ); + decimator->SetTargetReduction( targetReduction ); + decimator->SetPreserveTopology( 1 ); + decimator->Update(); + newPolyData = decimator->GetOutput(); + } + else + { + vtkSmartPointer decimator = vtkQuadricDecimation::New(); + decimator->SetInput( polyData ); + decimator->SetTargetReduction( targetReduction ); + decimator->Update(); + newPolyData = decimator->GetOutput(); + } + + if( newPolyData != 0 ) + { + static_cast(this->m_Node->GetData())->SetVtkPolyData(newPolyData); + this->m_Node->Update(); + this->UpdateNodeLabel(); + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); + } + + int endingNumberOfCells = newPolyData->GetNumberOfCells(); + int reducedCells = startingNumberOfCells - endingNumberOfCells; + + QString message; + if( reducedCells == 0 ) + message = "Decimation was not able to reduce any more cells from Mesh."; + else + message = QString("Decimation successful. %1 cells removed").arg(reducedCells); + + this->WaitCursorOff(); + this->ShowAutoCloseMessageDialog(message); + } + catch(std::exception& e) + { + this->WaitCursorOff(); + error = QString::fromStdString(e.what()); + } + catch(...) + { + this->WaitCursorOff(); + error = "An unknown error occured. Please report error at bugs.mitk.org."; + } + if( !error.isEmpty() ) + this->ShowAutoCloseErrorDialog(error); + } + else + this->DisableGui(); +} + +void QmitkMeshDecimationView::MessageBoxTimer() +{ + m_MessageBoxDisplayTime--; + QString text = m_MessageBoxText; + text.append( QString(" (Will close in %1 seconds)").arg(m_MessageBoxDisplayTime) ); + m_MessageBox->setText( text ); + + if( m_MessageBoxDisplayTime == 0 ) + { + m_MessageBox->accept(); + } +} + +void QmitkMeshDecimationView::ShowAutoCloseErrorDialog( const QString& error ) +{ + m_MessageBox = new QMessageBox(QMessageBox::Warning, "Warning", error, QMessageBox::Ok ); + m_MessageBoxDisplayTime = 5; + m_MessageBoxText = error; + + this->MessageBoxTimer(); + m_MessageBoxTimer->start(); + m_MessageBox->exec(); + m_MessageBoxTimer->stop(); + + delete m_MessageBox; + m_MessageBox = 0; +} + +void QmitkMeshDecimationView::ShowAutoCloseMessageDialog( const QString& message ) +{ + m_MessageBox = new QMessageBox(QMessageBox::Information, "Information", message, QMessageBox::Ok ); + m_MessageBoxDisplayTime = 5; + m_MessageBoxText = message; + + this->MessageBoxTimer(); + m_MessageBoxTimer->start(); + m_MessageBox->exec(); + m_MessageBoxTimer->stop(); + + delete m_MessageBox; + m_MessageBox = 0; +} diff --git a/Plugins/org.mitk.gui.qt.meshdecimation/src/internal/QmitkMeshDecimationView.h b/Plugins/org.mitk.gui.qt.meshdecimation/src/internal/QmitkMeshDecimationView.h new file mode 100644 index 0000000000..e333577be4 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.meshdecimation/src/internal/QmitkMeshDecimationView.h @@ -0,0 +1,72 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +Language: C++ +Date: $Date$ +Version: $Revision$ + +Copyright (c) German Cancer Research Center, Division of Medical and +Biological Informatics. All rights reserved. +See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#ifndef QmitkMeshDecimationView_h +#define QmitkMeshDecimationView_h + +#include +#include +#include +#include +#include +#include "ui_QmitkMeshDecimationView.h" + +/*! + \brief QmitkMeshDecimationView + + \warning This application module is not yet documented. Use "svn blame/praise/annotate" and ask the author to provide basic documentation. + + \sa QmitkFunctionality + \ingroup Functionalities +*/ +class QmitkMeshDecimationView : public QmitkAbstractView +{ +// this is needed for all Qt objects that should have a Qt meta-object +// (everything that derives from QObject and wants to have signal/slots) +Q_OBJECT +public: + static const std::string VIEW_ID; + + QmitkMeshDecimationView(); + virtual ~QmitkMeshDecimationView(); + + virtual void CreateQtPartControl(QWidget *parent); + virtual void SetFocus(); + + virtual void OnSelectionChanged(berry::IWorkbenchPart::Pointer, const QList&); +protected slots: + void Decimate(); + void MessageBoxTimer(); +protected: + void DisableGui(); + void UpdateNodeLabel(); + void ShowAutoCloseErrorDialog( const QString& error ); + void ShowAutoCloseMessageDialog( const QString& message ); + + Ui::QmitkMeshDecimationView* m_Controls; + mitk::WeakPointer m_Node; + QWidget* m_Parent; + QMessageBox* m_MessageBox; + int m_MessageBoxDisplayTime; + QString m_MessageBoxText; + QTimer *m_MessageBoxTimer; +}; + + + +#endif // _QMITKMESHSMOOTHINGVIEW_H_INCLUDED + diff --git a/Plugins/org.mitk.gui.qt.meshdecimation/src/internal/QmitkMeshDecimationView.ui b/Plugins/org.mitk.gui.qt.meshdecimation/src/internal/QmitkMeshDecimationView.ui new file mode 100644 index 0000000000..23d2dcd7f1 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.meshdecimation/src/internal/QmitkMeshDecimationView.ui @@ -0,0 +1,145 @@ + + + QmitkMeshDecimationView + + + + 0 + 0 + 389 + 811 + + + + + 0 + 0 + + + + QmitkTemplate + + + + + + + + Selected node: + + + + + + + none selected + + + + + + + + 132 + 0 + + + + Target reduction [percent]: + + + + + + + false + + + 1 + + + 100 + + + 50 + + + + + + + Decimation Type*: + + + true + + + + + + + false + + + + DecimatePro + + + + + Quadric + + + + + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">* Quadric Decimation reduces the mesh without accounting much for its topology. DecimatePro preserves topology best but does not garantuee the target reduction rate.</span></p></body></html> + + + true + + + + + + + false + + + Do image processing + + + Decimate + + + + + + + Qt::Vertical + + + QSizePolicy::Expanding + + + + 20 + 220 + + + + + + + + + + diff --git a/Plugins/org.mitk.gui.qt.meshdecimation/src/internal/mitkPluginActivator.cpp b/Plugins/org.mitk.gui.qt.meshdecimation/src/internal/mitkPluginActivator.cpp new file mode 100644 index 0000000000..0995ef5ffe --- /dev/null +++ b/Plugins/org.mitk.gui.qt.meshdecimation/src/internal/mitkPluginActivator.cpp @@ -0,0 +1,22 @@ +#include "mitkPluginActivator.h" + +#include + +#include "QmitkMeshDecimationView.h" + +namespace mitk { + +void PluginActivator::start(ctkPluginContext* context) +{ + BERRY_REGISTER_EXTENSION_CLASS(QmitkMeshDecimationView, context) + //BERRY_REGISTER_EXTENSION_CLASS(QmitkHexVolumeMesherView, context) +} + +void PluginActivator::stop(ctkPluginContext* context) +{ + Q_UNUSED(context) +} + +} + +Q_EXPORT_PLUGIN2(org_mbi_gui_qt_meshdecimation, mitk::PluginActivator) diff --git a/Plugins/org.mitk.gui.qt.meshdecimation/src/internal/mitkPluginActivator.h b/Plugins/org.mitk.gui.qt.meshdecimation/src/internal/mitkPluginActivator.h new file mode 100644 index 0000000000..a34be34be4 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.meshdecimation/src/internal/mitkPluginActivator.h @@ -0,0 +1,23 @@ +#ifndef MITKPLUGINACTIVATOR_H +#define MITKPLUGINACTIVATOR_H + +#include + +namespace mitk { + +class PluginActivator : + public QObject, public ctkPluginActivator +{ + Q_OBJECT + Q_INTERFACES(ctkPluginActivator) + +public: + + void start(ctkPluginContext* context); + void stop(ctkPluginContext* context); + +}; // PluginActivator + +} + +#endif // MITKPLUGINACTIVATOR_H