diff --git a/Modules/IGT/Common/mitkTrackingTypes.h b/Modules/IGT/Common/mitkTrackingTypes.h index e8c4fc310c..504ec669b0 100644 --- a/Modules/IGT/Common/mitkTrackingTypes.h +++ b/Modules/IGT/Common/mitkTrackingTypes.h @@ -1,237 +1,242 @@ /*=================================================================== 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. ===================================================================*/ #ifndef MITKTRACKINGTYPES_H_HEADER_INCLUDED_ #define MITKTRACKINGTYPES_H_HEADER_INCLUDED_ #include #include +#include #include namespace mitk { /**Documentation * \brief Error codes of NDI tracking devices */ enum NDIErrorCode { NDIOKAY = 0, NDIERROR = 1, SERIALINTERFACENOTSET, SERIALSENDERROR, SERIALRECEIVEERROR, SROMFILETOOLARGE, SROMFILETOOSMALL, NDICRCERROR, // reply has crc error, local computer detected the error NDIINVALIDCOMMAND, NDICOMMANDTOOLONG, NDICOMMANDTOOSHORT, NDICRCDOESNOTMATCH, // command had crc error, tracking device detected the error NDITIMEOUT, NDIUNABLETOSETNEWCOMMPARAMETERS, NDIINCORRECTNUMBEROFPARAMETERS, NDIINVALIDPORTHANDLE, NDIINVALIDTRACKINGPRIORITY, NDIINVALIDLED, NDIINVALIDLEDSTATE, NDICOMMANDINVALIDINCURRENTMODE, NDINOTOOLFORPORT, NDIPORTNOTINITIALIZED, NDISYSTEMNOTINITIALIZED, NDIUNABLETOSTOPTRACKING, NDIUNABLETOSTARTTRACKING, NDIINITIALIZATIONFAILED, NDIINVALIDVOLUMEPARAMETERS, NDICANTSTARTDIAGNOSTICMODE, NDICANTINITIRDIAGNOSTICS, NDIFAILURETOWRITESROM, NDIENABLEDTOOLSNOTSUPPORTED, NDICOMMANDPARAMETEROUTOFRANGE, NDINOMEMORYAVAILABLE, NDIPORTHANDLENOTALLOCATED, NDIPORTHASBECOMEUNOCCUPIED, NDIOUTOFHANDLES, NDIINCOMPATIBLEFIRMWAREVERSIONS, NDIINVALIDPORTDESCRIPTION, NDIINVALIDOPERATIONFORDEVICE, NDIWARNING, NDIUNKNOWNERROR, NDIUNEXPECTEDREPLY, UNKNOWNHANDLERETURNED, TRACKINGDEVICERESET, TRACKINGDEVICENOTSET }; /**Documentation * \brief identifier for tracking device. The way it is currently used * represents a product line rather than an actal type. Refactoring is a future option. */ enum TrackingDeviceType { NDIPolaris, ///< Polaris: optical Tracker from NDI NDIAurora, ///< Aurora: electromagnetic Tracker from NDI ClaronMicron, ///< Micron Tracker: optical Tracker from Claron IntuitiveDaVinci, ///< Intuitive Surgical: DaVinci Telemanipulator API Interface AscensionMicroBird, ///< Ascension microBird / PCIBird family VirtualTracker, ///< Virtual Tracking device class that produces random tracking coordinates TrackingSystemNotSpecified,///< entry for not specified or initialized tracking system TrackingSystemInvalid, ///< entry for invalid state (mainly for testing) NPOptitrack ///< NaturalPoint: Optitrack optical Tracking System }; /**Documentation * \brief Error codes of NDI tracking devices */ enum OperationMode { ToolTracking6D, ToolTracking5D, MarkerTracking3D, HybridTracking }; /** * /brief This structure defines key variables of a device model and type. * It is specifically used to find out which models belong to which vendor, and what volume * to use for a specific Model. Leaving VolumeModelLocation set to null will instruct the Generator * to generate a field to the best of his ability. HardwareCode stands for a hexadecimal string, * that represents the tracking volume. "X" stands for "hardwarecode is not known" or "tracking device has * no hardware code". For NDI devices it is used in the SetVolume() Method in mitkNDITrackingDevice.cpp. * The Pyramid Volume has the hardwarecode "4", but it is not supported yet. */ struct TrackingDeviceData { TrackingDeviceType Line; std::string Model; std::string VolumeModelLocation; std::string HardwareCode; }; /** * Here all supported devices are defined. Dont forget to introduce new Devices into the TrackingDeviceList Array at the bottom! * If a model does not have a corresponding tracking volume yet, pass an empty string to denote "No Model". pass "cube" to render * a default cube of 400x400 px. You can define additional magic strings in the TrackingVolumeGenerator. */ //############## NDI Aurora device data ############# static TrackingDeviceData DeviceDataAuroraCompact = {NDIAurora, "Aurora Compact", "NDIAuroraCompactFG_Dome.stl", "A"}; static TrackingDeviceData DeviceDataAuroraPlanarCube = {NDIAurora, "Aurora Planar (Cube)", "NDIAurora.stl", "9"}; static TrackingDeviceData DeviceDataAuroraPlanarDome = {NDIAurora, "Aurora Planar (Dome)","NDIAuroraPlanarFG_Dome.stl", "A"}; static TrackingDeviceData DeviceDataAuroraTabletop = {NDIAurora, "Aurora Tabletop", "NDIAuroraTabletopFG_Dome.stl", "A"}; // The following entry is for the tabletop prototype, which had an lower barrier of 8cm. The new version has a lower barrier of 12cm. //static TrackingDeviceData DeviceDataAuroraTabletopPrototype = {NDIAurora, "Aurora Tabletop Prototype", "NDIAuroraTabletopFG_Prototype_Dome.stl"}; //############## NDI Polaris device data ############ static TrackingDeviceData DeviceDataPolarisOldModel = {NDIPolaris, "Polaris (Old Model)", "NDIPolarisOldModel.stl", "0"}; //full hardware code of polaris spectra: 5-240000-153200-095000+057200+039800+056946+024303+029773+999999+99999924 static TrackingDeviceData DeviceDataPolarisSpectra = {NDIPolaris, "Polaris Spectra", "NDIPolarisSpectra.stl", "5-2"}; //full hardware code of polaris spectra (extended pyramid): 5-300000-153200-095000+057200+039800+056946+024303+029773+999999+07350024 static TrackingDeviceData DeviceDataSpectraExtendedPyramid = {NDIPolaris, "Polaris Spectra (Extended Pyramid)", "NDIPolarisSpectraExtendedPyramid.stl","5-3"}; static TrackingDeviceData DeviceDataPolarisVicra = {NDIPolaris, "Polaris Vicra", "NDIPolarisVicra.stl","7"}; //############## NDI Polaris device data ############ static TrackingDeviceData DeviceDataNPOptitrack = {NPOptitrack, "Optitrack", "cube", "X"}; //############## other device data ################## static TrackingDeviceData DeviceDataDaVinci = {IntuitiveDaVinci, "Intuitive DaVinci", "IntuitiveDaVinci.stl","X"}; static TrackingDeviceData DeviceDataMicroBird = {AscensionMicroBird, "Ascension MicroBird", "", "X"}; static TrackingDeviceData DeviceDataVirtualTracker = {VirtualTracker, "Virtual Tracker", "cube","X"}; static TrackingDeviceData DeviceDataMicronTrackerH40 = {ClaronMicron, "Micron Tracker H40", "ClaronMicron.stl", "X"}; static TrackingDeviceData DeviceDataUnspecified = {TrackingSystemNotSpecified, "Unspecified System", "cube","X"}; // Careful when changing the "invalid" device: The mitkTrackingTypeTest is using it's data. static TrackingDeviceData DeviceDataInvalid = {TrackingSystemInvalid, "Invalid Tracking System", "", "X"}; //This list should hold all devices defined above! static TrackingDeviceData TrackingDeviceList[] = {DeviceDataAuroraPlanarCube, DeviceDataAuroraPlanarDome, DeviceDataAuroraCompact, DeviceDataAuroraTabletop, DeviceDataMicronTrackerH40, DeviceDataPolarisSpectra, DeviceDataPolarisVicra, DeviceDataNPOptitrack, DeviceDataDaVinci, DeviceDataMicroBird, DeviceDataVirtualTracker, DeviceDataUnspecified, DeviceDataSpectraExtendedPyramid, DeviceDataInvalid, DeviceDataPolarisOldModel}; /** * /brief Returns all devices compatibel to the given Line of Devices */ MitkIGT_EXPORT std::vector GetDeviceDataForLine(TrackingDeviceType Type); /** * /brief Returns the first TracingDeviceData mathing a given line. Useful for backward compatibility * with the old way to manage Devices */ MitkIGT_EXPORT TrackingDeviceData GetFirstCompatibleDeviceDataForLine(TrackingDeviceType Type); /** * /brief Returns the device Data set matching the model name or the invalid device, if none was found */ MitkIGT_EXPORT TrackingDeviceData GetDeviceDataByName(const std::string& modelName); /**Documentation * \brief activation rate of IR illuminator for NDI Polaris tracking device */ enum IlluminationActivationRate { Hz20 = 20, Hz30 = 30, Hz60 = 60 }; /**Documentation * \brief Data transfer mode for NDI tracking devices */ enum DataTransferMode { TX = 0, BX = 1 }; /**Documentation * \brief Query mode for NDI tracking devices */ enum PHSRQueryType { ALL = 0x00, FREED = 0x01, OCCUPIED = 0x02, INITIALIZED = 0x03, ENABLED = 0x04 }; typedef itk::Point MarkerPointType; typedef std::vector MarkerPointContainerType; /** * \brief Defines the tools (arms) of the daVinci system: * PSM1 - Patient side manipulator 1 * PSM2 - Patient side manipulator 2 * ECM - Endoscopic camera manipulator * MTML - Left master target manipulator * MTMR - Right master target manipulator * PSM - Patient side manipulator 3 (if not existent, its data will always be zero) **/ enum DaVinciToolType { PSM1 = 0, PSM2 = 1, ECM = 2, MTML = 3, MTMR = 4, PSM = 5, //UIEvents = 6, }; + + /** definition of a colors for IGT */ + static mitk::Color IGTColor_WARNING = mitk::ColorProperty::New(1.0f, 0.0f, 0.0f)->GetColor(); + static mitk::Color IGTColor_VALID = mitk::ColorProperty::New(0.0f, 1.0f, 0.0f)->GetColor(); } // namespace mitk #endif /* MITKTRACKINGTYPES_H_HEADER_INCLUDED_ */ diff --git a/Modules/IGTUI/Qmitk/QmitkToolTrackingStatusWidget.cpp b/Modules/IGTUI/Qmitk/QmitkToolTrackingStatusWidget.cpp index 975265da61..b2d4e7cbe5 100644 --- a/Modules/IGTUI/Qmitk/QmitkToolTrackingStatusWidget.cpp +++ b/Modules/IGTUI/Qmitk/QmitkToolTrackingStatusWidget.cpp @@ -1,267 +1,267 @@ /*=================================================================== 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 "QmitkToolTrackingStatusWidget.h" QmitkToolTrackingStatusWidget::QmitkToolTrackingStatusWidget(QWidget* parent) : QWidget(parent), m_Controls(NULL), m_StatusLabels (NULL), m_NavigationDatas(NULL) { m_ShowPositions = false; m_ShowQuaternions = false; m_Alignment = Qt::AlignHCenter; m_Style = QmitkToolTrackingStatusWidget::VerticalUpperStyle; CreateQtPartControl( this ); } void QmitkToolTrackingStatusWidget::SetStyle(QmitkToolTrackingStatusWidget::Style newStyle) { //set new style m_Style = newStyle; //update current labels to show them in the new style Refresh(); } void QmitkToolTrackingStatusWidget::SetShowPositions(bool enable) { m_ShowPositions = enable; //update current labels Refresh(); } void QmitkToolTrackingStatusWidget::SetShowQuaternions(bool enable) { m_ShowQuaternions = enable; //update current labels Refresh(); } void QmitkToolTrackingStatusWidget::SetTextAlignment(Qt::AlignmentFlag alignment) { m_Alignment = alignment; //update current labels Refresh(); } QmitkToolTrackingStatusWidget::~QmitkToolTrackingStatusWidget() { //m_Controls = NULL; - delete m_StatusLabels; - delete m_NavigationDatas; + if (m_StatusLabels!=NULL) {delete m_StatusLabels;} + if (m_NavigationDatas!=NULL) {delete m_NavigationDatas;} } void QmitkToolTrackingStatusWidget::CreateQtPartControl(QWidget *parent) { if (!m_Controls) { // create GUI widgets m_Controls = new Ui::QmitkToolTrackingStatusWidgetControls; m_Controls->setupUi(parent); this->CreateConnections(); //add empty label AddEmptyLabel(); } } void QmitkToolTrackingStatusWidget::CreateConnections() { } void QmitkToolTrackingStatusWidget::SetNavigationDatas(std::vector* navDatas) { m_NavigationDatas = navDatas; } void QmitkToolTrackingStatusWidget::AddNavigationData(mitk::NavigationData::Pointer nd) { if(m_NavigationDatas == NULL) m_NavigationDatas = new std::vector(); m_NavigationDatas->push_back(nd); } void QmitkToolTrackingStatusWidget::Refresh(int posPrecision, int quatPrecision) { if(m_NavigationDatas == NULL || m_NavigationDatas->size() <= 0) { RemoveGuiLabels(); AddEmptyLabel(); return; } mitk::NavigationData* navData; for(unsigned int i = 0; i < m_NavigationDatas->size(); i++) { navData = m_NavigationDatas->at(i).GetPointer(); QString name(navData->GetName()); QString pos = ""; QString quat = ""; if (m_ShowPositions) { mitk::Point3D position = navData->GetPosition(); pos = " [" + QString::number(position[0],'f',posPrecision) + ";" + QString::number(position[1],'f',posPrecision) + ";" + QString::number(position[2],'f',posPrecision) + "]"; } if (m_ShowQuaternions) { mitk::Quaternion quaternion = navData->GetOrientation(); quat = " / [qx:" + QString::number(quaternion.x(),'f',quatPrecision) + ";qy:" + QString::number(quaternion.y(),'f',quatPrecision) + ";qz:" + QString::number(quaternion.z(),'f',quatPrecision) + ";qr:" + QString::number(quaternion.r()) + "]"; } if(!(m_StatusLabels->at(i)->text() == name+pos+quat)) m_StatusLabels->at(i)->setText(name+pos+quat); if(navData->IsDataValid()) m_StatusLabels->at(i)->setStyleSheet("QLabel{background-color: #8bff8b }"); else m_StatusLabels->at(i)->setStyleSheet("QLabel{background-color: #ff7878 }"); } } void QmitkToolTrackingStatusWidget::ShowStatusLabels() { RemoveGuiLabels(); if(m_NavigationDatas == NULL || m_NavigationDatas->size() <= 0) { RemoveGuiLabels(); AddEmptyLabel(); return; } m_StatusLabels = new QVector(); mitk::NavigationData* navData; QLabel* label; for(unsigned int i = 0; i < m_NavigationDatas->size(); i++) { navData = m_NavigationDatas->at(i).GetPointer(); QString name(navData->GetName()); label = new QLabel(name, this); label->setObjectName(name); label->setAlignment(m_Alignment | Qt::AlignVCenter); label->setFrameStyle(QFrame::Panel | QFrame::Sunken); m_StatusLabels->append(label); if (m_Style == QmitkToolTrackingStatusWidget::VerticalUpperStyle) m_Controls->m_VerticalLayout->addWidget(m_StatusLabels->at(i)); else m_Controls->m_GridLayout->addWidget(m_StatusLabels->at(i),0,i); } } void QmitkToolTrackingStatusWidget::PreShowTools(mitk::NavigationToolStorage::Pointer toolStorage) { RemoveGuiLabels(); QLabel* label; for(unsigned int i = 0; i < toolStorage->GetToolCount(); i++) { QString name(toolStorage->GetTool(i)->GetToolName().c_str()); label = new QLabel(name, this); label->setObjectName(name); label->setAlignment(m_Alignment | Qt::AlignVCenter); label->setFrameStyle(QFrame::Panel | QFrame::Sunken); label->setStyleSheet("QLabel{background-color: #dddddd }"); if (m_Style == QmitkToolTrackingStatusWidget::VerticalUpperStyle) m_Controls->m_VerticalLayout->addWidget(label); else m_Controls->m_GridLayout->addWidget(label); } } void QmitkToolTrackingStatusWidget::RemoveStatusLabels() { //remove GUI elements RemoveGuiLabels(); //clear members if(m_StatusLabels != NULL && m_StatusLabels->size() > 0) { delete m_StatusLabels; m_StatusLabels = new QVector< QLabel* >(); } if(m_NavigationDatas != NULL && m_NavigationDatas->size() > 0) { delete m_NavigationDatas; m_NavigationDatas = new std::vector(); } //add empty label AddEmptyLabel(); } void QmitkToolTrackingStatusWidget::RemoveGuiLabels() { while(m_Controls->m_GridLayout->count() > 0 || m_Controls->m_VerticalLayout->count() > 0) { if (m_Controls->m_GridLayout->count() > 0) { QWidget* actWidget = m_Controls->m_GridLayout->itemAt(0)->widget(); m_Controls->m_GridLayout->removeWidget(actWidget); delete actWidget; } else if (m_Controls->m_VerticalLayout->count() > 0) { QWidget* actWidget = m_Controls->m_VerticalLayout->itemAt(0)->widget(); m_Controls->m_VerticalLayout->removeWidget(actWidget); delete actWidget; } } } void QmitkToolTrackingStatusWidget::AddEmptyLabel() { //add a label which tells that no tools are loaded yet QLabel* label = new QLabel("No tools loaded yet.", this); label->setObjectName("No tools loaded yet."); label->setAlignment(m_Alignment | Qt::AlignVCenter); label->setFrameStyle(QFrame::Panel | QFrame::Sunken); label->setStyleSheet("QLabel{background-color: #dddddd }"); if (m_Style == QmitkToolTrackingStatusWidget::VerticalUpperStyle) m_Controls->m_VerticalLayout->addWidget(label); else m_Controls->m_GridLayout->addWidget(label); } diff --git a/Modules/US/USNavigation/mitkUSCombinedModality.cpp b/Modules/US/USNavigation/mitkUSCombinedModality.cpp index 6440c6da46..a1d647a123 100644 --- a/Modules/US/USNavigation/mitkUSCombinedModality.cpp +++ b/Modules/US/USNavigation/mitkUSCombinedModality.cpp @@ -1,541 +1,542 @@ /*=================================================================== 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 "mitkUSCombinedModality.h" #include "mitkUSDevice.h" #include "mitkNavigationDataSource.h" #include "mitkImageReadAccessor.h" #include #include #include "mitkTrackingDeviceSource.h" // US Control Interfaces #include "mitkUSControlInterfaceProbes.h" #include "mitkUSControlInterfaceBMode.h" #include "mitkUSControlInterfaceDoppler.h" #include //TempIncludes #include const std::string mitk::USCombinedModality::DeviceClassIdentifier = "org.mitk.modules.us.USCombinedModality"; const char* mitk::USCombinedModality::DefaultProbeIdentifier = "default"; const char* mitk::USCombinedModality::ProbeAndDepthSeperator = "_"; mitk::USCombinedModality::USCombinedModality(USDevice::Pointer usDevice, NavigationDataSource::Pointer trackingDevice, std::string manufacturer, std::string model) : mitk::USDevice(manufacturer, model), m_UltrasoundDevice(usDevice), m_TrackingDevice(trackingDevice), m_SmoothingFilter(mitk::NavigationDataSmoothingFilter::New()), m_DelayFilter(mitk::NavigationDataDelayFilter::New(0)), m_NumberOfSmoothingValues(0), m_DelayCount(0) { this->RebuildFilterPipeline(); //create a new output (for the image data) mitk::Image::Pointer newOutput = mitk::Image::New(); this->SetNthOutput(0,newOutput); // Combined Modality should not spawn an own acquire thread, because // image acquiring is done by the included us device this->SetSpawnAcquireThread(false); } mitk::USCombinedModality::~USCombinedModality() { } std::string mitk::USCombinedModality::GetDeviceClass() { return DeviceClassIdentifier; } mitk::USImageSource::Pointer mitk::USCombinedModality::GetUSImageSource() { if (m_UltrasoundDevice.IsNull()) { MITK_ERROR("USCombinedModality")("USDevice") << "UltrasoundDevice must not be null."; mitkThrow() << "UltrasoundDevice must not be null."; } return m_UltrasoundDevice->GetUSImageSource(); } mitk::USAbstractControlInterface::Pointer mitk::USCombinedModality::GetControlInterfaceCustom() { if (m_UltrasoundDevice.IsNull()) { MITK_ERROR("USCombinedModality")("USDevice") << "UltrasoundDevice must not be null."; mitkThrow() << "UltrasoundDevice must not be null."; } return m_UltrasoundDevice->GetControlInterfaceCustom(); } mitk::USControlInterfaceBMode::Pointer mitk::USCombinedModality::GetControlInterfaceBMode() { if (m_UltrasoundDevice.IsNull()) { MITK_ERROR("USCombinedModality")("USDevice") << "UltrasoundDevice must not be null."; mitkThrow() << "UltrasoundDevice must not be null."; } return m_UltrasoundDevice->GetControlInterfaceBMode(); } mitk::USControlInterfaceProbes::Pointer mitk::USCombinedModality::GetControlInterfaceProbes() { if (m_UltrasoundDevice.IsNull()) { MITK_ERROR("USCombinedModality")("USDevice") << "UltrasoundDevice must not be null."; mitkThrow() << "UltrasoundDevice must not be null."; } return m_UltrasoundDevice->GetControlInterfaceProbes(); } mitk::USControlInterfaceDoppler::Pointer mitk::USCombinedModality::GetControlInterfaceDoppler() { if (m_UltrasoundDevice.IsNull()) { MITK_ERROR("USCombinedModality")("USDevice") << "UltrasoundDevice must not be null."; mitkThrow() << "UltrasoundDevice must not be null."; } return m_UltrasoundDevice->GetControlInterfaceDoppler(); } void mitk::USCombinedModality::UnregisterOnService() { if (m_DeviceState == State_Activated) { this->Deactivate(); } if (m_DeviceState == State_Connected) { this->Disconnect(); } mitk::USDevice::UnregisterOnService(); } mitk::AffineTransform3D::Pointer mitk::USCombinedModality::GetCalibration() { return this->GetCalibration(this->GetCurrentDepthValue(), this->GetIdentifierForCurrentProbe()); } mitk::AffineTransform3D::Pointer mitk::USCombinedModality::GetCalibration(std::string depth) { return this->GetCalibration(depth, this->GetIdentifierForCurrentProbe()); } mitk::AffineTransform3D::Pointer mitk::USCombinedModality::GetCalibration(std::string depth, std::string probe) { // make sure that there is no '/' which would cause problems for TinyXML std::replace(probe.begin(), probe.end(), '/', '-'); // create identifier for calibration from probe and depth std::string calibrationKey = probe + mitk::USCombinedModality::ProbeAndDepthSeperator + depth; // find calibration for combination of probe identifier and depth std::map::iterator calibrationIterator = m_Calibrations.find(calibrationKey); if (calibrationIterator == m_Calibrations.end()) { return 0; } return calibrationIterator->second; } void mitk::USCombinedModality::SetCalibration (mitk::AffineTransform3D::Pointer calibration) { if (calibration.IsNull()) { MITK_WARN << "Null pointer passed to SetCalibration of mitk::USDevice. Ignoring call."; return; } std::string calibrationKey = this->GetIdentifierForCurrentCalibration(); if (calibrationKey.empty()) { MITK_WARN << "Could not get a key for the calibration -> Calibration cannot be set."; return; } m_Calibrations[calibrationKey] = calibration; } bool mitk::USCombinedModality::RemoveCalibration() { return this->RemoveCalibration(this->GetCurrentDepthValue(), this->GetIdentifierForCurrentProbe()); } bool mitk::USCombinedModality::RemoveCalibration(std::string depth) { return this->RemoveCalibration(depth, this->GetIdentifierForCurrentProbe()); } bool mitk::USCombinedModality::RemoveCalibration(std::string depth, std::string probe) { // make sure that there is no '/' which would cause problems for TinyXML std::replace(probe.begin(), probe.end(), '/', '-'); // create identifier for calibration from probe and depth std::string calibrationKey = probe + mitk::USCombinedModality::ProbeAndDepthSeperator + depth; return m_Calibrations.erase(calibrationKey) > 0; } void mitk::USCombinedModality::SetNumberOfSmoothingValues(unsigned int numberOfSmoothingValues) { unsigned int oldNumber = m_NumberOfSmoothingValues; m_NumberOfSmoothingValues = numberOfSmoothingValues; // if filter should be activated or deactivated if ( ( oldNumber == 0 && numberOfSmoothingValues != 0 ) || ( oldNumber != 0 && numberOfSmoothingValues == 0 ) ) { this->RebuildFilterPipeline(); } m_SmoothingFilter->SetNumerOfValues(numberOfSmoothingValues); } void mitk::USCombinedModality::SetDelayCount(unsigned int delayCount) { unsigned int oldCount = m_DelayCount; m_DelayCount = delayCount; // if filter should be activated or deactivated if ( ( oldCount == 0 && delayCount != 0 ) || ( oldCount != 0 && delayCount == 0 ) ) { this->RebuildFilterPipeline(); } m_DelayFilter->SetDelay(delayCount); } bool mitk::USCombinedModality::OnInitialization() { if (m_UltrasoundDevice.IsNull()) { MITK_ERROR("USCombinedModality")("USDevice") << "UltrasoundDevice must not be null."; mitkThrow() << "UltrasoundDevice must not be null."; } if ( m_UltrasoundDevice->GetDeviceState() < mitk::USDevice::State_Initialized ) { return m_UltrasoundDevice->Initialize(); } else { return true; } } bool mitk::USCombinedModality::OnConnection() { if (m_UltrasoundDevice.IsNull()) { MITK_ERROR("USCombinedModality")("USDevice") << "UltrasoundDevice must not be null."; mitkThrow() << "UltrasoundDevice must not be null."; } // connect ultrasound device only if it is not already connected if ( m_UltrasoundDevice->GetDeviceState() >= mitk::USDevice::State_Connected ) { return true; } else { return m_UltrasoundDevice->Connect(); } } bool mitk::USCombinedModality::OnDisconnection() { if (m_UltrasoundDevice.IsNull()) { MITK_ERROR("USCombinedModality")("USDevice") << "UltrasoundDevice must not be null."; mitkThrow() << "UltrasoundDevice must not be null."; } return m_UltrasoundDevice->Disconnect(); } bool mitk::USCombinedModality::OnActivation() { if ( m_UltrasoundDevice.IsNull() ) { MITK_ERROR("USCombinedModality")("USDevice") << "UltrasoundDevice must not be null."; mitkThrow() << "UltrasoundDevice must not be null."; } mitk::TrackingDeviceSource::Pointer trackingDeviceSource = dynamic_cast(m_TrackingDevice.GetPointer()); if ( trackingDeviceSource.IsNull() ) { MITK_WARN("USCombinedModality")("USDevice") << "Cannot start tracking as TrackingDeviceSource is null."; } trackingDeviceSource->StartTracking(); // activate ultrasound device only if it is not already activated if ( m_UltrasoundDevice->GetDeviceState() >= mitk::USDevice::State_Activated ) { return true; } else { return m_UltrasoundDevice->Activate(); } } bool mitk::USCombinedModality::OnDeactivation() { if ( m_UltrasoundDevice.IsNull() ) { MITK_ERROR("USCombinedModality")("USDevice") << "UltrasoundDevice must not be null."; mitkThrow() << "UltrasoundDevice must not be null."; } mitk::TrackingDeviceSource::Pointer trackingDeviceSource = dynamic_cast(m_TrackingDevice.GetPointer()); if ( trackingDeviceSource.IsNull() ) { MITK_WARN("USCombinedModality")("USDevice") << "Cannot stop tracking as TrackingDeviceSource is null."; } trackingDeviceSource->StopTracking(); m_UltrasoundDevice->Deactivate(); return m_UltrasoundDevice->GetIsConnected(); } void mitk::USCombinedModality::OnFreeze(bool freeze) { if (m_UltrasoundDevice.IsNull()) { MITK_ERROR("USCombinedModality")("USDevice") << "UltrasoundDevice must not be null."; mitkThrow() << "UltrasoundDevice must not be null."; } m_UltrasoundDevice->SetIsFreezed(freeze); mitk::TrackingDeviceSource::Pointer trackingDeviceSource = dynamic_cast(m_TrackingDevice.GetPointer()); if ( trackingDeviceSource.IsNull() ) { MITK_WARN("USCombinedModality")("USDevice") << "Cannot freeze tracking."; } else { if ( freeze ) { trackingDeviceSource->StopTracking(); } else { trackingDeviceSource->StartTracking(); } } } mitk::NavigationDataSource::Pointer mitk::USCombinedModality::GetNavigationDataSource() { return m_LastFilter.GetPointer(); } bool mitk::USCombinedModality::GetIsCalibratedForCurrentStatus() { return m_Calibrations.find(this->GetIdentifierForCurrentCalibration()) != m_Calibrations.end(); } bool mitk::USCombinedModality::GetContainsAtLeastOneCalibration() { return ! m_Calibrations.empty(); } void mitk::USCombinedModality::GenerateData() { // update ultrasound image source and get current output then m_UltrasoundDevice->Modified(); m_UltrasoundDevice->Update(); mitk::Image::Pointer image = m_UltrasoundDevice->GetOutput(); if ( image.IsNull() || ! image->IsInitialized() ) { return; } // get output and initialize it if it wasn't initialized before mitk::Image::Pointer output = this->GetOutput(); if ( ! output->IsInitialized() ) { output->Initialize(image); } mitk::ImageReadAccessor inputReadAccessor(image, image->GetSliceData(0,0,0)); - output->SetSlice(inputReadAccessor.GetData()); + output->SetSlice(inputReadAccessor.GetData()); //copy image data + output->GetGeometry()->SetSpacing(image->GetGeometry()->GetSpacing()); //copy spacing because this might also change std::string calibrationKey = this->GetIdentifierForCurrentCalibration(); if ( ! calibrationKey.empty() ) { std::map::iterator calibrationIterator = m_Calibrations.find(calibrationKey); if ( calibrationIterator != m_Calibrations.end()) { // transform image according to callibration if one is set // for current configuration of probe and depth output->GetGeometry()->SetIndexToWorldTransform(calibrationIterator->second); } } } std::string mitk::USCombinedModality::SerializeCalibration() { std::stringstream result; result << "" << std::endl; // For each calibration in the set for (std::map::iterator it = m_Calibrations.begin(); it != m_Calibrations.end(); it++) { mitk::AffineTransform3D::MatrixType matrix = it->second->GetMatrix(); mitk::AffineTransform3D::TranslationType translation = it->second->GetTranslation(); TiXmlElement elem(it->first); // Serialize Matrix elem.SetDoubleAttribute("M00", matrix[0][0]); elem.SetDoubleAttribute("M01", matrix[0][1]); elem.SetDoubleAttribute("M02", matrix[0][2]); elem.SetDoubleAttribute("M10", matrix[1][0]); elem.SetDoubleAttribute("M11", matrix[1][1]); elem.SetDoubleAttribute("M12", matrix[1][2]); elem.SetDoubleAttribute("M20", matrix[2][0]); elem.SetDoubleAttribute("M21", matrix[2][1]); elem.SetDoubleAttribute("M22", matrix[2][2]); // Serialize Offset elem.SetDoubleAttribute("T0", translation[0]); elem.SetDoubleAttribute("T1", translation[1]); elem.SetDoubleAttribute("T2", translation[2]); result << elem << std::endl; } result << "" << std::endl; return result.str(); } void mitk::USCombinedModality::DeserializeCalibration(const std::string& xmlString, bool clearPreviousCalibrations) { // Sanitize Input if (xmlString == "") { MITK_ERROR << "Empty string passed to Deserialize() method of CombinedModality. Aborting..."; mitkThrow() << "Empty string passed to Deserialize() method of CombinedModality. Aborting..."; return; } // Clear previous calibrations if necessary if (clearPreviousCalibrations) m_Calibrations.clear(); // Parse Input TiXmlDocument doc; if(!doc.Parse(xmlString.c_str())) { MITK_ERROR << "Unable to deserialize calibrations in CombinedModality. Error was: " << doc.ErrorDesc(); mitkThrow() << "Unable to deserialize calibrations in CombinedModality. Error was: " << doc.ErrorDesc(); return; } TiXmlElement* root = doc.FirstChildElement(); if(root == NULL) { MITK_ERROR << "Unable to deserialize calibrations in CombinedModality. String contained no root element."; mitkThrow() << "Unable to deserialize calibrations in CombinedModality. String contained no root element."; return; } // Read Calibrations for(TiXmlElement* elem = root->FirstChildElement(); elem != NULL; elem = elem->NextSiblingElement()) { mitk::AffineTransform3D::MatrixType matrix; mitk::AffineTransform3D::OffsetType translation; std::string calibName = elem->Value(); // Deserialize Matrix elem->QueryDoubleAttribute("M00", &matrix[0][0]); elem->QueryDoubleAttribute("M01", &matrix[0][1]); elem->QueryDoubleAttribute("M02", &matrix[0][2]); elem->QueryDoubleAttribute("M10", &matrix[1][0]); elem->QueryDoubleAttribute("M11", &matrix[1][1]); elem->QueryDoubleAttribute("M12", &matrix[1][2]); elem->QueryDoubleAttribute("M20", &matrix[2][0]); elem->QueryDoubleAttribute("M21", &matrix[2][1]); elem->QueryDoubleAttribute("M22", &matrix[2][2]); // Deserialize Offset elem->QueryDoubleAttribute("T0", &translation[0]); elem->QueryDoubleAttribute("T1", &translation[1]); elem->QueryDoubleAttribute("T2", &translation[2]); mitk::AffineTransform3D::Pointer calibration = mitk::AffineTransform3D::New(); calibration->SetMatrix(matrix); calibration->SetTranslation(translation); m_Calibrations[calibName] = calibration; } } std::string mitk::USCombinedModality::GetIdentifierForCurrentCalibration() { return this->GetIdentifierForCurrentProbe() + mitk::USCombinedModality::ProbeAndDepthSeperator + this->GetCurrentDepthValue(); } std::string mitk::USCombinedModality::GetIdentifierForCurrentProbe() { us::ServiceProperties usdeviceProperties = m_UltrasoundDevice->GetServiceProperties(); us::ServiceProperties::const_iterator probeIt = usdeviceProperties.find( mitk::USCombinedModality::GetPropertyKeys().US_PROPKEY_PROBES_SELECTED); // get probe identifier from control interface for probes std::string probeName = mitk::USCombinedModality::DefaultProbeIdentifier; if (probeIt != usdeviceProperties.end()) { probeName = (probeIt->second).ToString(); } // make sure that there is no '/' which would cause problems for TinyXML std::replace(probeName.begin(), probeName.end(), '/', '-'); return probeName; } std::string mitk::USCombinedModality::GetCurrentDepthValue() { us::ServiceProperties usdeviceProperties = m_UltrasoundDevice->GetServiceProperties(); // get string for depth value from the micro service properties std::string depth; us::ServiceProperties::iterator depthIterator = usdeviceProperties.find( mitk::USCombinedModality::GetPropertyKeys().US_PROPKEY_BMODE_DEPTH); if (depthIterator != usdeviceProperties.end()) { depth = depthIterator->second.ToString(); } else { depth = "0"; } return depth; } void mitk::USCombinedModality::RebuildFilterPipeline() { m_LastFilter = m_TrackingDevice; if ( m_NumberOfSmoothingValues > 0 ) { for (unsigned int i = 0; i < m_TrackingDevice->GetNumberOfOutputs(); i++) { m_SmoothingFilter->SetInput(i, m_LastFilter->GetOutput(i)); } m_LastFilter = m_SmoothingFilter; } if ( m_DelayCount > 0 ) { for (unsigned int i = 0; i < m_TrackingDevice->GetNumberOfOutputs(); i++) { m_DelayFilter->SetInput(i, m_LastFilter->GetOutput(i)); } m_LastFilter = m_DelayFilter; } } diff --git a/Plugins/org.mitk.gui.qt.igttracking/src/internal/QmitkMITKIGTTrackingToolboxView.cpp b/Plugins/org.mitk.gui.qt.igttracking/src/internal/QmitkMITKIGTTrackingToolboxView.cpp index 916e167485..0bbf267181 100644 --- a/Plugins/org.mitk.gui.qt.igttracking/src/internal/QmitkMITKIGTTrackingToolboxView.cpp +++ b/Plugins/org.mitk.gui.qt.igttracking/src/internal/QmitkMITKIGTTrackingToolboxView.cpp @@ -1,1182 +1,1224 @@ /*=================================================================== 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 "QmitkMITKIGTTrackingToolboxView.h" #include "QmitkStdMultiWidget.h" // Qt #include #include #include // MITK #include #include #include #include #include #include #include #include #include #include // vtk #include //for exceptions #include #include const std::string QmitkMITKIGTTrackingToolboxView::VIEW_ID = "org.mitk.views.mitkigttrackingtoolbox"; QmitkMITKIGTTrackingToolboxView::QmitkMITKIGTTrackingToolboxView() : QmitkFunctionality() , m_Controls( 0 ) , m_MultiWidget( NULL ) { m_TrackingTimer = new QTimer(this); m_tracking = false; m_logging = false; m_loggedFrames = 0; //initialize worker thread m_WorkerThread = new QThread(); m_Worker = new QmitkMITKIGTTrackingToolboxViewWorker(); } QmitkMITKIGTTrackingToolboxView::~QmitkMITKIGTTrackingToolboxView() { this->StoreUISettings(); try { //clean up worker thread if(m_WorkerThread) {delete m_WorkerThread;} if(m_Worker) {delete m_Worker;} //remove the tracking volume this->GetDataStorage()->Remove(m_TrackingVolumeNode); //remove the tool storage if(m_toolStorage) {m_toolStorage->UnRegisterMicroservice();} if(m_TrackingDeviceSource) {m_TrackingDeviceSource->UnRegisterMicroservice();} } catch(std::exception& e) {MITK_WARN << "Unexpected exception during clean up of tracking toolbox view: " << e.what();} catch(...) {MITK_WARN << "Unexpected unknown error during clean up of tracking toolbox view!";} this->StoreUISettings(); } void QmitkMITKIGTTrackingToolboxView::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::QmitkMITKIGTTrackingToolboxViewControls; m_Controls->setupUi( parent ); //create connections connect( m_Controls->m_LoadTools, SIGNAL(clicked()), this, SLOT(OnLoadTools()) ); connect( m_Controls->m_Connect, SIGNAL(clicked()), this, SLOT(OnConnect()) ); connect( m_Controls->m_Disconnect, SIGNAL(clicked()), this, SLOT(OnDisconnect()) ); connect( m_Controls->m_StartTracking, SIGNAL(clicked()), this, SLOT(OnStartTracking()) ); connect( m_Controls->m_StopTracking, SIGNAL(clicked()), this, SLOT(OnStopTracking()) ); connect( m_TrackingTimer, SIGNAL(timeout()), this, SLOT(UpdateTrackingTimer())); connect( m_Controls->m_ChooseFile, SIGNAL(clicked()), this, SLOT(OnChooseFileClicked())); connect( m_Controls->m_StartLogging, SIGNAL(clicked()), this, SLOT(StartLogging())); connect( m_Controls->m_StopLogging, SIGNAL(clicked()), this, SLOT(StopLogging())); connect( m_Controls->m_VolumeSelectionBox, SIGNAL(currentIndexChanged(QString)), this, SLOT(OnTrackingVolumeChanged(QString))); connect( m_Controls->m_ShowTrackingVolume, SIGNAL(clicked()), this, SLOT(OnShowTrackingVolumeChanged())); connect( m_Controls->m_AutoDetectTools, SIGNAL(clicked()), this, SLOT(OnAutoDetectTools())); connect( m_Controls->m_ResetTools, SIGNAL(clicked()), this, SLOT(OnResetTools())); connect( m_Controls->m_AddSingleTool, SIGNAL(clicked()), this, SLOT(OnAddSingleTool())); connect( m_Controls->m_NavigationToolCreationWidget, SIGNAL(NavigationToolFinished()), this, SLOT(OnAddSingleToolFinished())); connect( m_Controls->m_NavigationToolCreationWidget, SIGNAL(Canceled()), this, SLOT(OnAddSingleToolCanceled())); connect( m_Controls->m_csvFormat, SIGNAL(clicked()), this, SLOT(OnToggleFileExtension())); connect( m_Controls->m_xmlFormat, SIGNAL(clicked()), this, SLOT(OnToggleFileExtension())); //connections for the tracking device configuration widget connect( m_Controls->m_configurationWidget, SIGNAL(TrackingDeviceSelectionChanged()), this, SLOT(OnTrackingDeviceChanged())); connect( m_Controls->m_configurationWidget, SIGNAL(ProgressStarted()), this, SLOT(DisableOptionsButtons())); connect( m_Controls->m_configurationWidget, SIGNAL(ProgressStarted()), this, SLOT(DisableTrackingConfigurationButtons())); connect( m_Controls->m_configurationWidget, SIGNAL(ProgressStarted()), this, SLOT(DisableTrackingControls())); connect( m_Controls->m_configurationWidget, SIGNAL(ProgressFinished()), this, SLOT(EnableOptionsButtons())); connect( m_Controls->m_configurationWidget, SIGNAL(ProgressFinished()), this, SLOT(EnableTrackingConfigurationButtons())); connect( m_Controls->m_configurationWidget, SIGNAL(ProgressFinished()), this, SLOT(EnableTrackingControls())); //connect worker thread connect(m_Worker, SIGNAL(AutoDetectToolsFinished(bool,QString)), this, SLOT(OnAutoDetectToolsFinished(bool,QString)) ); connect(m_Worker, SIGNAL(ConnectDeviceFinished(bool,QString)), this, SLOT(OnConnectFinished(bool,QString)) ); connect(m_Worker, SIGNAL(StartTrackingFinished(bool,QString)), this, SLOT(OnStartTrackingFinished(bool,QString)) ); connect(m_Worker, SIGNAL(StopTrackingFinished(bool,QString)), this, SLOT(OnStopTrackingFinished(bool,QString)) ); connect(m_Worker, SIGNAL(DisconnectDeviceFinished(bool,QString)), this, SLOT(OnDisconnectFinished(bool,QString)) ); connect(m_WorkerThread,SIGNAL(started()), m_Worker, SLOT(ThreadFunc()) ); //move the worker to the thread m_Worker->moveToThread(m_WorkerThread); //initialize widgets m_Controls->m_configurationWidget->EnableAdvancedUserControl(false); m_Controls->m_TrackingToolsStatusWidget->SetShowPositions(true); m_Controls->m_TrackingToolsStatusWidget->SetTextAlignment(Qt::AlignLeft); //initialize tracking volume node m_TrackingVolumeNode = mitk::DataNode::New(); m_TrackingVolumeNode->SetName("TrackingVolume"); - m_TrackingVolumeNode->SetOpacity(0.25); m_TrackingVolumeNode->SetBoolProperty("Backface Culling",true); mitk::Color red; red.SetRed(1); m_TrackingVolumeNode->SetColor(red); //initialize buttons m_Controls->m_Connect->setEnabled(true); m_Controls->m_Disconnect->setEnabled(false); m_Controls->m_StartTracking->setEnabled(false); m_Controls->m_StopTracking->setEnabled(false); m_Controls->m_AutoDetectTools->setVisible(false); //only visible if tracking device is Aurora //Update List of available models for selected tool. std::vector Compatibles; if ( (m_Controls == NULL) || //check all these stuff for NULL, latterly this causes crashes from time to time (m_Controls->m_configurationWidget == NULL) || (m_Controls->m_configurationWidget->GetTrackingDevice().IsNull())) { MITK_ERROR << "Couldn't get current tracking device or an object is NULL, something went wrong!"; return; } else { Compatibles = mitk::GetDeviceDataForLine( m_Controls->m_configurationWidget->GetTrackingDevice()->GetType()); } m_Controls->m_VolumeSelectionBox->clear(); for(int i = 0; i < Compatibles.size(); i++) { m_Controls->m_VolumeSelectionBox->addItem(Compatibles[i].Model.c_str()); } //initialize tool storage m_toolStorage = mitk::NavigationToolStorage::New(GetDataStorage()); m_toolStorage->SetName("TrackingToolbox Default Storage"); m_toolStorage->RegisterAsMicroservice("no tracking device"); //set home directory as default path for logfile m_Controls->m_LoggingFileName->setText(QDir::toNativeSeparators(QDir::homePath()) + QDir::separator() + "logfile.csv"); //tracking device may be changed already by the persistence of the //QmitkTrackingDeciveConfigurationWidget this->OnTrackingDeviceChanged(); this->LoadUISettings(); - //add tracking volume node only to data storage if the volume should be shown - if ( m_Controls->m_ShowTrackingVolume->isChecked() ) - { - this->GetDataStorage()->Add(m_TrackingVolumeNode); - } + //add tracking volume node only to data storage + this->GetDataStorage()->Add(m_TrackingVolumeNode); + if (!m_Controls->m_ShowTrackingVolume->isChecked()) m_TrackingVolumeNode->SetOpacity(0.0); + else m_TrackingVolumeNode->SetOpacity(0.25); } } void QmitkMITKIGTTrackingToolboxView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget) { m_MultiWidget = &stdMultiWidget; } void QmitkMITKIGTTrackingToolboxView::StdMultiWidgetNotAvailable() { m_MultiWidget = NULL; } void QmitkMITKIGTTrackingToolboxView::OnLoadTools() { //read in filename QString filename = QFileDialog::getOpenFileName(NULL,tr("Open Tool Storage"), "/", tr("Tool Storage Files (*.IGTToolStorage)")); if (filename.isNull()) return; //read tool storage from disk std::string errorMessage = ""; mitk::NavigationToolStorageDeserializer::Pointer myDeserializer = mitk::NavigationToolStorageDeserializer::New(GetDataStorage()); // try-catch block for exceptions try { this->ReplaceCurrentToolStorage(myDeserializer->Deserialize(filename.toStdString()),filename.toStdString()); } catch(mitk::IGTException) { std::string errormessage = "Error during deserializing. Problems with file,please check the file?"; QMessageBox::warning(NULL, "IGTPlayer: Error", errormessage.c_str()); return; } if(m_toolStorage->isEmpty()) { errorMessage = myDeserializer->GetErrorMessage(); MessageBox(errorMessage); return; } //update label Poco::Path myPath = Poco::Path(filename.toStdString()); //use this to seperate filename from path QString toolLabel = QString("Loaded Tools: ") + QString::number(m_toolStorage->GetToolCount()) + " Tools from " + myPath.getFileName().c_str(); m_Controls->m_toolLabel->setText(toolLabel); //update tool preview m_Controls->m_TrackingToolsStatusWidget->RemoveStatusLabels(); m_Controls->m_TrackingToolsStatusWidget->PreShowTools(m_toolStorage); //save filename for persistent storage m_ToolStorageFilename = filename; } void QmitkMITKIGTTrackingToolboxView::OnResetTools() { this->ReplaceCurrentToolStorage(mitk::NavigationToolStorage::New(GetDataStorage()),"TrackingToolbox Default Storage"); m_Controls->m_TrackingToolsStatusWidget->RemoveStatusLabels(); QString toolLabel = QString("Loaded Tools: "); m_Controls->m_toolLabel->setText(toolLabel); m_ToolStorageFilename = ""; } void QmitkMITKIGTTrackingToolboxView::OnConnect() { MITK_INFO << "Connect Clicked"; //check if everything is ready to start tracking if (this->m_toolStorage.IsNull()) { MessageBox("Error: No Tools Loaded Yet!"); return; } else if (this->m_toolStorage->GetToolCount() == 0) { MessageBox("Error: No Way To Track Without Tools!"); return; } //parse tracking device data mitk::TrackingDeviceData data = mitk::DeviceDataUnspecified; QString qstr = m_Controls->m_VolumeSelectionBox->currentText(); if ( (! qstr.isNull()) || (! qstr.isEmpty()) ) { std::string str = qstr.toStdString(); data = mitk::GetDeviceDataByName(str); //Data will be set later, after device generation } //initialize worker thread m_Worker->SetWorkerMethod(QmitkMITKIGTTrackingToolboxViewWorker::eConnectDevice); m_Worker->SetTrackingDevice(this->m_Controls->m_configurationWidget->GetTrackingDevice()); m_Worker->SetInverseMode(m_Controls->m_InverseMode->isChecked()); m_Worker->SetNavigationToolStorage(this->m_toolStorage); m_Worker->SetTrackingDeviceData(data); //start worker thread m_WorkerThread->start(); //disable buttons this->m_Controls->m_MainWidget->setEnabled(false); } void QmitkMITKIGTTrackingToolboxView::OnConnectFinished(bool success, QString errorMessage) { m_WorkerThread->quit(); //enable buttons this->m_Controls->m_MainWidget->setEnabled(true); if (!success) { MITK_WARN << errorMessage.toStdString(); MessageBox(errorMessage.toStdString()); return; } //get data from worker thread m_TrackingDeviceSource = m_Worker->GetTrackingDeviceSource(); m_TrackingDeviceData = m_Worker->GetTrackingDeviceData(); m_ToolVisualizationFilter = m_Worker->GetToolVisualizationFilter(); //enable/disable Buttons m_Controls->m_Disconnect->setEnabled(true); m_Controls->m_StartTracking->setEnabled(true); m_Controls->m_StopTracking->setEnabled(false); m_Controls->m_Connect->setEnabled(false); DisableOptionsButtons(); DisableTrackingConfigurationButtons(); m_Controls->m_configurationWidget->ConfigurationFinished(); m_Controls->m_TrackingControlLabel->setText("Status: connected"); } void QmitkMITKIGTTrackingToolboxView::OnDisconnect() { m_Worker->SetWorkerMethod(QmitkMITKIGTTrackingToolboxViewWorker::eDisconnectDevice); m_WorkerThread->start(); m_Controls->m_MainWidget->setEnabled(false); } void QmitkMITKIGTTrackingToolboxView::OnDisconnectFinished(bool success, QString errorMessage) { m_WorkerThread->quit(); m_Controls->m_MainWidget->setEnabled(true); if (!success) { MITK_WARN << errorMessage.toStdString(); MessageBox(errorMessage.toStdString()); return; } //enable/disable Buttons m_Controls->m_Disconnect->setEnabled(false); m_Controls->m_StartTracking->setEnabled(false); m_Controls->m_StopTracking->setEnabled(false); m_Controls->m_Connect->setEnabled(true); EnableOptionsButtons(); EnableTrackingConfigurationButtons(); m_Controls->m_configurationWidget->Reset(); m_Controls->m_TrackingControlLabel->setText("Status: disconnected"); } void QmitkMITKIGTTrackingToolboxView::OnStartTracking() { m_Worker->SetWorkerMethod(QmitkMITKIGTTrackingToolboxViewWorker::eStartTracking); m_WorkerThread->start(); this->m_Controls->m_MainWidget->setEnabled(false); } void QmitkMITKIGTTrackingToolboxView::OnStartTrackingFinished(bool success, QString errorMessage) { m_WorkerThread->quit(); this->m_Controls->m_MainWidget->setEnabled(true); if(!success) { MessageBox(errorMessage.toStdString()); MITK_WARN << errorMessage.toStdString(); return; } m_TrackingTimer->start(1000/(m_Controls->m_UpdateRate->value())); m_Controls->m_TrackingControlLabel->setText("Status: tracking"); //connect the tool visualization widget for(int i=0; iGetNumberOfOutputs(); i++) { m_Controls->m_TrackingToolsStatusWidget->AddNavigationData(m_TrackingDeviceSource->GetOutput(i)); } m_Controls->m_TrackingToolsStatusWidget->ShowStatusLabels(); if (m_Controls->m_ShowToolQuaternions->isChecked()) {m_Controls->m_TrackingToolsStatusWidget->SetShowQuaternions(true);} else {m_Controls->m_TrackingToolsStatusWidget->SetShowQuaternions(false);} //show tracking volume this->OnTrackingVolumeChanged(m_Controls->m_VolumeSelectionBox->currentText()); //enable/disable Buttons m_Controls->m_Disconnect->setEnabled(true); m_Controls->m_StartTracking->setEnabled(false); m_Controls->m_StopTracking->setEnabled(true); m_Controls->m_Connect->setEnabled(false); m_tracking = true; this->GlobalReinit(); } void QmitkMITKIGTTrackingToolboxView::OnStopTracking() { if (!m_tracking) return; m_TrackingTimer->stop(); m_Worker->SetWorkerMethod(QmitkMITKIGTTrackingToolboxViewWorker::eStopTracking); m_WorkerThread->start(); m_Controls->m_MainWidget->setEnabled(false); } void QmitkMITKIGTTrackingToolboxView::OnStopTrackingFinished(bool success, QString errorMessage) { m_WorkerThread->quit(); m_Controls->m_MainWidget->setEnabled(true); if(!success) { MessageBox(errorMessage.toStdString()); MITK_WARN << errorMessage.toStdString(); return; } m_Controls->m_TrackingControlLabel->setText("Status: connected"); if (m_logging) StopLogging(); m_Controls->m_TrackingToolsStatusWidget->RemoveStatusLabels(); m_Controls->m_TrackingToolsStatusWidget->PreShowTools(m_toolStorage); m_tracking = false; //enable/disable Buttons m_Controls->m_Disconnect->setEnabled(true); m_Controls->m_StartTracking->setEnabled(true); m_Controls->m_StopTracking->setEnabled(false); m_Controls->m_Connect->setEnabled(false); this->GlobalReinit(); } void QmitkMITKIGTTrackingToolboxView::OnTrackingDeviceChanged() { mitk::TrackingDeviceType Type; if (m_Controls->m_configurationWidget->GetTrackingDevice().IsNotNull()) { Type = m_Controls->m_configurationWidget->GetTrackingDevice()->GetType(); //enable controls because device is valid m_Controls->m_TrackingToolsGoupBox->setEnabled(true); m_Controls->m_TrackingControlsGroupBox->setEnabled(true); } else { Type = mitk::TrackingSystemNotSpecified; MessageBox("Error: This tracking device is not included in this project. Please make sure that the device is installed and activated in your MITK build."); m_Controls->m_TrackingToolsGoupBox->setEnabled(false); m_Controls->m_TrackingControlsGroupBox->setEnabled(false); return; } // Code to enable/disable device specific buttons if (Type == mitk::NDIAurora) //Aurora { m_Controls->m_AutoDetectTools->setVisible(true); m_Controls->m_AddSingleTool->setEnabled(false); } else //Polaris or Microntracker { m_Controls->m_AutoDetectTools->setVisible(false); m_Controls->m_AddSingleTool->setEnabled(true); } // Code to select appropriate tracking volume for current type std::vector Compatibles = mitk::GetDeviceDataForLine(Type); m_Controls->m_VolumeSelectionBox->clear(); for(int i = 0; i < Compatibles.size(); i++) { m_Controls->m_VolumeSelectionBox->addItem(Compatibles[i].Model.c_str()); } } void QmitkMITKIGTTrackingToolboxView::OnTrackingVolumeChanged(QString qstr) { if (qstr.isNull()) return; if (qstr.isEmpty()) return; - if (m_Controls->m_ShowTrackingVolume->isChecked()) - { - mitk::TrackingVolumeGenerator::Pointer volumeGenerator = mitk::TrackingVolumeGenerator::New(); - std::string str = qstr.toStdString(); + mitk::TrackingVolumeGenerator::Pointer volumeGenerator = mitk::TrackingVolumeGenerator::New(); - mitk::TrackingDeviceData data = mitk::GetDeviceDataByName(str); - m_TrackingDeviceData = data; + std::string str = qstr.toStdString(); - volumeGenerator->SetTrackingDeviceData(data); - volumeGenerator->Update(); + mitk::TrackingDeviceData data = mitk::GetDeviceDataByName(str); + m_TrackingDeviceData = data; - mitk::Surface::Pointer volumeSurface = volumeGenerator->GetOutput(); + volumeGenerator->SetTrackingDeviceData(data); + volumeGenerator->Update(); - m_TrackingVolumeNode->SetData(volumeSurface); + mitk::Surface::Pointer volumeSurface = volumeGenerator->GetOutput(); - GlobalReinit(); - } + m_TrackingVolumeNode->SetData(volumeSurface); + + if (!m_Controls->m_ShowTrackingVolume->isChecked()) m_TrackingVolumeNode->SetOpacity(0.0); + else m_TrackingVolumeNode->SetOpacity(0.25); + + GlobalReinit(); } void QmitkMITKIGTTrackingToolboxView::OnShowTrackingVolumeChanged() { if (m_Controls->m_ShowTrackingVolume->isChecked()) { OnTrackingVolumeChanged(m_Controls->m_VolumeSelectionBox->currentText()); - GetDataStorage()->Add(m_TrackingVolumeNode); + m_TrackingVolumeNode->SetOpacity(0.25); } else { - GetDataStorage()->Remove(m_TrackingVolumeNode); - GlobalReinit(); + m_TrackingVolumeNode->SetOpacity(0.0); } } void QmitkMITKIGTTrackingToolboxView::OnAutoDetectTools() { if (m_Controls->m_configurationWidget->GetTrackingDevice()->GetType() == mitk::NDIAurora) { DisableTrackingConfigurationButtons(); m_Worker->SetWorkerMethod(QmitkMITKIGTTrackingToolboxViewWorker::eAutoDetectTools); m_Worker->SetTrackingDevice(m_Controls->m_configurationWidget->GetTrackingDevice().GetPointer()); m_Worker->SetDataStorage(this->GetDataStorage()); m_WorkerThread->start(); //disable controls until worker thread is finished this->m_Controls->m_MainWidget->setEnabled(false); } } void QmitkMITKIGTTrackingToolboxView::OnAutoDetectToolsFinished(bool success, QString errorMessage) { m_WorkerThread->quit(); //enable controls again this->m_Controls->m_MainWidget->setEnabled(true); if(!success) { MITK_WARN << errorMessage.toStdString(); MessageBox(errorMessage.toStdString()); EnableTrackingConfigurationButtons(); return; } mitk::NavigationToolStorage::Pointer autoDetectedStorage = m_Worker->GetNavigationToolStorage(); //save detected tools this->ReplaceCurrentToolStorage(autoDetectedStorage,"Autodetected NDI Aurora Storage"); //update label QString toolLabel = QString("Loaded Tools: ") + QString::number(m_toolStorage->GetToolCount()) + " Tools (Auto Detected)"; m_Controls->m_toolLabel->setText(toolLabel); //update tool preview m_Controls->m_TrackingToolsStatusWidget->RemoveStatusLabels(); m_Controls->m_TrackingToolsStatusWidget->PreShowTools(m_toolStorage); EnableTrackingConfigurationButtons(); if (m_toolStorage->GetToolCount()>0) { //ask the user if he wants to save the detected tools QMessageBox msgBox; switch(m_toolStorage->GetToolCount()) { case 1: msgBox.setText("Found one tool!"); break; default: msgBox.setText("Found " + QString::number(m_toolStorage->GetToolCount()) + " tools!"); } msgBox.setInformativeText("Do you want to save this tools as tool storage, so you can load them again?"); msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); msgBox.setDefaultButton(QMessageBox::No); int ret = msgBox.exec(); if (ret == 16384) //yes { //ask the user for a filename QString fileName = QFileDialog::getSaveFileName(NULL, tr("Save File"),"/",tr("*.IGTToolStorage")); //check for empty filename if(fileName == "") {return;} mitk::NavigationToolStorageSerializer::Pointer mySerializer = mitk::NavigationToolStorageSerializer::New(); //when Serialize method is used exceptions are thrown, need to be adapted //try-catch block for exception handling in Serializer try { mySerializer->Serialize(fileName.toStdString(),m_toolStorage); } catch(mitk::IGTException) { std::string errormessage = "Error during serialization. Please check the Zip file."; QMessageBox::warning(NULL, "IGTPlayer: Error", errormessage.c_str()); } return; } else if (ret == 65536) //no { return; } } } void QmitkMITKIGTTrackingToolboxView::MessageBox(std::string s) { QMessageBox msgBox; msgBox.setText(s.c_str()); msgBox.exec(); } void QmitkMITKIGTTrackingToolboxView::UpdateTrackingTimer() { + //update filter m_ToolVisualizationFilter->Update(); MITK_DEBUG << "Number of outputs ToolVisualizationFilter: " << m_ToolVisualizationFilter->GetNumberOfIndexedOutputs(); MITK_DEBUG << "Number of inputs ToolVisualizationFilter: " << m_ToolVisualizationFilter->GetNumberOfIndexedInputs(); - mitk::RenderingManager::GetInstance()->RequestUpdateAll(); + + //update tool colors to show tool status + for(int i=0; iGetNumberOfIndexedOutputs(); i++) + { + mitk::NavigationData::Pointer currentTool = m_ToolVisualizationFilter->GetOutput(i); + if(currentTool->IsDataValid()) + {this->m_toolStorage->GetTool(i)->GetDataNode()->SetColor(mitk::IGTColor_VALID);} + else + {this->m_toolStorage->GetTool(i)->GetDataNode()->SetColor(mitk::IGTColor_WARNING);} + } + + //update logging if (m_logging) { this->m_loggingFilter->Update(); m_loggedFrames = this->m_loggingFilter->GetNumberOfRecordedSteps(); this->m_Controls->m_LoggedFramesLabel->setText("Logged Frames: "+QString::number(m_loggedFrames)); //check if logging stopped automatically if((m_loggedFrames>1)&&(!m_loggingFilter->GetRecording())){StopLogging();} + } + + //refresh view and status widget + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); + m_Controls->m_TrackingToolsStatusWidget->Refresh(); } m_Controls->m_TrackingToolsStatusWidget->Refresh(); } void QmitkMITKIGTTrackingToolboxView::OnChooseFileClicked() { QDir currentPath = QFileInfo(m_Controls->m_LoggingFileName->text()).dir(); // if no path was selected (QDir would select current working dir then) or the // selected path does not exist -> use home directory if ( currentPath == QDir() || ! currentPath.exists() ) { currentPath = QDir(QDir::homePath()); } QString filename = QFileDialog::getSaveFileName(NULL,tr("Choose Logging File"), currentPath.absolutePath(), "*.*"); if (filename == "") return; this->m_Controls->m_LoggingFileName->setText(filename); this->OnToggleFileExtension(); } // bug-16470: toggle file extension after clicking on radio button void QmitkMITKIGTTrackingToolboxView::OnToggleFileExtension() { QString currentInputText = this->m_Controls->m_LoggingFileName->text(); QString currentFile = QFileInfo(currentInputText).baseName(); QDir currentPath = QFileInfo(currentInputText).dir(); if(currentFile.isEmpty()) { currentFile = "logfile"; } // Setting currentPath to default home path when currentPath is empty or it does not exist if(currentPath == QDir() || !currentPath.exists()) { currentPath = QDir::homePath(); } // check if csv radio button is clicked if(this->m_Controls->m_csvFormat->isChecked()) { // you needn't add a seperator to the input text when currentpath is the rootpath if(currentPath.isRoot()) { this->m_Controls->m_LoggingFileName->setText(QDir::toNativeSeparators(currentPath.absolutePath()) + currentFile + ".csv"); } else { this->m_Controls->m_LoggingFileName->setText(QDir::toNativeSeparators(currentPath.absolutePath()) + QDir::separator() + currentFile + ".csv"); } } // check if xml radio button is clicked else if(this->m_Controls->m_xmlFormat->isChecked()) { // you needn't add a seperator to the input text when currentpath is the rootpath if(currentPath.isRoot()) { this->m_Controls->m_LoggingFileName->setText(QDir::toNativeSeparators(currentPath.absolutePath()) + currentFile + ".xml"); } else { this->m_Controls->m_LoggingFileName->setText(QDir::toNativeSeparators(currentPath.absolutePath()) + QDir::separator() + currentFile + ".xml"); } } } void QmitkMITKIGTTrackingToolboxView::StartLogging() { if (m_ToolVisualizationFilter.IsNull()) { MessageBox("Cannot activate logging without a connected device. Configure and connect a tracking device first."); return; } if (!m_logging) { //initialize logging filter m_loggingFilter = mitk::NavigationDataRecorder::New(); m_loggingFilter->ConnectTo(m_ToolVisualizationFilter); if (m_Controls->m_LoggingLimit->isChecked()){m_loggingFilter->SetRecordCountLimit(m_Controls->m_LoggedFramesLimit->value());} //start filter with try-catch block for exceptions try { m_loggingFilter->StartRecording(); } catch(mitk::IGTException) { std::string errormessage = "Error during start recording. Recorder already started recording?"; QMessageBox::warning(NULL, "IGTPlayer: Error", errormessage.c_str()); m_loggingFilter->StopRecording(); return; } //update labels / logging variables this->m_Controls->m_LoggingLabel->setText("Logging ON"); this->m_Controls->m_LoggedFramesLabel->setText("Logged Frames: 0"); m_loggedFrames = 0; m_logging = true; DisableLoggingButtons(); } } void QmitkMITKIGTTrackingToolboxView::StopLogging() { if (m_logging) { //stop logging m_loggingFilter->StopRecording(); m_logging = false; //update GUI this->m_Controls->m_LoggingLabel->setText("Logging OFF"); EnableLoggingButtons(); //write the results to a file if(m_Controls->m_csvFormat->isChecked()) { mitk::NavigationDataSetWriterCSV* writer = new mitk::NavigationDataSetWriterCSV(); writer->Write(this->m_Controls->m_LoggingFileName->text().toStdString(),m_loggingFilter->GetNavigationDataSet()); delete writer; } else if (m_Controls->m_xmlFormat->isChecked()) { mitk::NavigationDataSetWriterXML* writer = new mitk::NavigationDataSetWriterXML(); writer->Write(this->m_Controls->m_LoggingFileName->text().toStdString(),m_loggingFilter->GetNavigationDataSet()); delete writer; } } } void QmitkMITKIGTTrackingToolboxView::OnAddSingleTool() { QString Identifier = "Tool#"; if (m_toolStorage.IsNotNull()) Identifier += QString::number(m_toolStorage->GetToolCount()); else Identifier += "0"; m_Controls->m_NavigationToolCreationWidget->Initialize(GetDataStorage(),Identifier.toStdString()); m_Controls->m_NavigationToolCreationWidget->SetTrackingDeviceType(m_Controls->m_configurationWidget->GetTrackingDevice()->GetType(),false); m_Controls->m_TrackingToolsWidget->setCurrentIndex(1); //disable tracking volume during tool editing lastTrackingVolumeState = m_Controls->m_ShowTrackingVolume->isChecked(); if (lastTrackingVolumeState) m_Controls->m_ShowTrackingVolume->click(); GlobalReinit(); } void QmitkMITKIGTTrackingToolboxView::OnAddSingleToolFinished() { m_Controls->m_TrackingToolsWidget->setCurrentIndex(0); if (this->m_toolStorage.IsNull()) { //this shouldn't happen! MITK_WARN << "No ToolStorage available, cannot add tool, aborting!"; return; } m_toolStorage->AddTool(m_Controls->m_NavigationToolCreationWidget->GetCreatedTool()); m_Controls->m_TrackingToolsStatusWidget->PreShowTools(m_toolStorage); QString toolLabel = QString("Loaded Tools: "); //enable tracking volume again if (lastTrackingVolumeState) m_Controls->m_ShowTrackingVolume->click(); GlobalReinit(); } void QmitkMITKIGTTrackingToolboxView::OnAddSingleToolCanceled() { m_Controls->m_TrackingToolsWidget->setCurrentIndex(0); //enable tracking volume again if (lastTrackingVolumeState) m_Controls->m_ShowTrackingVolume->click(); GlobalReinit(); } void QmitkMITKIGTTrackingToolboxView::GlobalReinit() { // get all nodes that have not set "includeInBoundingBox" to false mitk::NodePredicateNot::Pointer pred = mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("includeInBoundingBox", mitk::BoolProperty::New(false))); mitk::DataStorage::SetOfObjects::ConstPointer rs = this->GetDataStorage()->GetSubset(pred); // calculate bounding geometry of these nodes mitk::TimeGeometry::Pointer bounds = this->GetDataStorage()->ComputeBoundingGeometry3D(rs, "visible"); // initialize the views to the bounding geometry mitk::RenderingManager::GetInstance()->InitializeViews(bounds); } void QmitkMITKIGTTrackingToolboxView::DisableLoggingButtons() { m_Controls->m_StartLogging->setEnabled(false); m_Controls->m_LoggingFileName->setEnabled(false); m_Controls->m_ChooseFile->setEnabled(false); m_Controls->m_LoggingLimit->setEnabled(false); m_Controls->m_LoggedFramesLimit->setEnabled(false); m_Controls->m_csvFormat->setEnabled(false); m_Controls->m_xmlFormat->setEnabled(false); m_Controls->m_StopLogging->setEnabled(true); } void QmitkMITKIGTTrackingToolboxView::EnableLoggingButtons() { m_Controls->m_StartLogging->setEnabled(true); m_Controls->m_LoggingFileName->setEnabled(true); m_Controls->m_ChooseFile->setEnabled(true); m_Controls->m_LoggingLimit->setEnabled(true); m_Controls->m_LoggedFramesLimit->setEnabled(true); m_Controls->m_csvFormat->setEnabled(true); m_Controls->m_xmlFormat->setEnabled(true); m_Controls->m_StopLogging->setEnabled(false); } void QmitkMITKIGTTrackingToolboxView::DisableOptionsButtons() { m_Controls->m_ShowTrackingVolume->setEnabled(false); m_Controls->m_UpdateRate->setEnabled(false); m_Controls->m_ShowToolQuaternions->setEnabled(false); m_Controls->m_OptionsUpdateRateLabel->setEnabled(false); } void QmitkMITKIGTTrackingToolboxView::EnableOptionsButtons() { m_Controls->m_ShowTrackingVolume->setEnabled(true); m_Controls->m_UpdateRate->setEnabled(true); m_Controls->m_ShowToolQuaternions->setEnabled(true); m_Controls->m_OptionsUpdateRateLabel->setEnabled(true); } void QmitkMITKIGTTrackingToolboxView::EnableTrackingControls() { m_Controls->m_TrackingControlsGroupBox->setEnabled(true); } void QmitkMITKIGTTrackingToolboxView::DisableTrackingControls() { m_Controls->m_TrackingControlsGroupBox->setEnabled(false); } void QmitkMITKIGTTrackingToolboxView::EnableTrackingConfigurationButtons() { m_Controls->m_AutoDetectTools->setEnabled(true); if (m_Controls->m_configurationWidget->GetTrackingDevice()->GetType() != mitk::NDIAurora) m_Controls->m_AddSingleTool->setEnabled(true); m_Controls->m_LoadTools->setEnabled(true); m_Controls->m_ResetTools->setEnabled(true); } void QmitkMITKIGTTrackingToolboxView::DisableTrackingConfigurationButtons() { m_Controls->m_AutoDetectTools->setEnabled(false); if (m_Controls->m_configurationWidget->GetTrackingDevice()->GetType() != mitk::NDIAurora) m_Controls->m_AddSingleTool->setEnabled(false); m_Controls->m_LoadTools->setEnabled(false); m_Controls->m_ResetTools->setEnabled(false); } void QmitkMITKIGTTrackingToolboxView::ReplaceCurrentToolStorage(mitk::NavigationToolStorage::Pointer newStorage, std::string newStorageName) { //first: get rid of the old one //don't reset if there is no tool storage. BugFix #17793 if ( m_toolStorage.IsNotNull() ){ m_toolStorage->UnLockStorage(); //only to be sure... m_toolStorage->UnRegisterMicroservice(); m_toolStorage = NULL; } //now: replace by the new one m_toolStorage = newStorage; m_toolStorage->SetName(newStorageName); m_toolStorage->RegisterAsMicroservice("no tracking device"); } void QmitkMITKIGTTrackingToolboxView::StoreUISettings() { // persistence service does not directly work in plugins for now // -> using QSettings QSettings settings; settings.beginGroup(QString::fromStdString(VIEW_ID)); // set the values of some widgets and attrbutes to the QSettings settings.setValue("ShowTrackingVolume", QVariant(m_Controls->m_ShowTrackingVolume->isChecked())); settings.setValue("toolStorageFilename", QVariant(m_ToolStorageFilename)); settings.setValue("VolumeSelectionBox", QVariant(m_Controls->m_VolumeSelectionBox->currentIndex())); settings.endGroup(); } void QmitkMITKIGTTrackingToolboxView::LoadUISettings() { // persistence service does not directly work in plugins for now // -> using QSettings QSettings settings; settings.beginGroup(QString::fromStdString(VIEW_ID)); // set some widgets and attributes by the values from the QSettings m_Controls->m_ShowTrackingVolume->setChecked(settings.value("ShowTrackingVolume", true).toBool()); m_Controls->m_VolumeSelectionBox->setCurrentIndex(settings.value("VolumeSelectionBox", 0).toInt()); m_ToolStorageFilename = settings.value("toolStorageFilename", QVariant("")).toString(); settings.endGroup(); // try to deserialize the tool storage from the given tool storage file name if ( ! m_ToolStorageFilename.isEmpty() ) { // try-catch block for exceptions try { mitk::NavigationToolStorageDeserializer::Pointer myDeserializer = mitk::NavigationToolStorageDeserializer::New(GetDataStorage()); m_toolStorage->UnRegisterMicroservice(); m_toolStorage = myDeserializer->Deserialize(m_ToolStorageFilename.toStdString()); m_toolStorage->RegisterAsMicroservice("no tracking device"); //update label Poco::Path myPath = Poco::Path(m_ToolStorageFilename.toStdString()); //use this to seperate filename from path QString toolLabel = QString("Loaded Tools: ") + QString::number(m_toolStorage->GetToolCount()) + " Tools from " + myPath.getFileName().c_str(); m_Controls->m_toolLabel->setText(toolLabel); //update tool preview m_Controls->m_TrackingToolsStatusWidget->RemoveStatusLabels(); m_Controls->m_TrackingToolsStatusWidget->PreShowTools(m_toolStorage); } catch(mitk::IGTException) { MITK_WARN("QmitkMITKIGTTrackingToolBoxView") << "Error during restoring tools. Problems with file ("<OnResetTools(); //if there where errors reset the tool storage to avoid problems later on } } } void QmitkMITKIGTTrackingToolboxViewWorker::SetWorkerMethod(WorkerMethod w) { m_WorkerMethod = w; } void QmitkMITKIGTTrackingToolboxViewWorker::SetTrackingDevice(mitk::TrackingDevice::Pointer t) { m_TrackingDevice = t; } void QmitkMITKIGTTrackingToolboxViewWorker::SetDataStorage(mitk::DataStorage::Pointer d) { m_DataStorage = d; } void QmitkMITKIGTTrackingToolboxViewWorker::SetInverseMode(bool mode) { m_InverseMode = mode; } void QmitkMITKIGTTrackingToolboxViewWorker::SetTrackingDeviceData(mitk::TrackingDeviceData d) { m_TrackingDeviceData = d; } void QmitkMITKIGTTrackingToolboxViewWorker::SetNavigationToolStorage(mitk::NavigationToolStorage::Pointer n) { m_NavigationToolStorage = n; } void QmitkMITKIGTTrackingToolboxViewWorker::ThreadFunc() { switch(m_WorkerMethod) { case eAutoDetectTools: this->AutoDetectTools(); break; case eConnectDevice: this->ConnectDevice(); break; case eStartTracking: this->StartTracking(); break; case eStopTracking: this->StopTracking(); break; case eDisconnectDevice: this->DisconnectDevice(); break; default: MITK_WARN << "Undefined worker method was set ... something went wrong!"; break; } } void QmitkMITKIGTTrackingToolboxViewWorker::AutoDetectTools() { mitk::ProgressBar::GetInstance()->AddStepsToDo(4); mitk::NavigationToolStorage::Pointer autoDetectedStorage = mitk::NavigationToolStorage::New(m_DataStorage); mitk::NDITrackingDevice::Pointer currentDevice = dynamic_cast(m_TrackingDevice.GetPointer()); try { currentDevice->OpenConnection(); mitk::ProgressBar::GetInstance()->Progress(); currentDevice->StartTracking(); } catch(mitk::Exception& e) { QString message = QString("Warning, can not auto-detect tools! (") + QString(e.GetDescription()) + QString(")"); //MessageBox(message.toStdString()); //TODO: give message to the user here! MITK_WARN << message.toStdString(); mitk::ProgressBar::GetInstance()->Progress(4); emit AutoDetectToolsFinished(false,message.toStdString().c_str()); return; } for (int i=0; iGetToolCount(); i++) { //create a navigation tool with sphere as surface std::stringstream toolname; toolname << "AutoDetectedTool" << i; mitk::NavigationTool::Pointer newTool = mitk::NavigationTool::New(); newTool->SetSerialNumber(dynamic_cast(currentDevice->GetTool(i))->GetSerialNumber()); newTool->SetIdentifier(toolname.str()); newTool->SetTrackingDeviceType(mitk::NDIAurora); mitk::DataNode::Pointer newNode = mitk::DataNode::New(); mitk::Surface::Pointer mySphere = mitk::Surface::New(); vtkSphereSource *vtkData = vtkSphereSource::New(); vtkData->SetRadius(3.0f); vtkData->SetCenter(0.0, 0.0, 0.0); vtkData->Update(); mySphere->SetVtkPolyData(vtkData->GetOutput()); vtkData->Delete(); newNode->SetData(mySphere); newNode->SetName(toolname.str()); newTool->SetDataNode(newNode); autoDetectedStorage->AddTool(newTool); } m_NavigationToolStorage = autoDetectedStorage; currentDevice->StopTracking(); mitk::ProgressBar::GetInstance()->Progress(); currentDevice->CloseConnection(); emit AutoDetectToolsFinished(true,""); mitk::ProgressBar::GetInstance()->Progress(4); } void QmitkMITKIGTTrackingToolboxViewWorker::ConnectDevice() { std::string message = ""; mitk::ProgressBar::GetInstance()->AddStepsToDo(10); //build the IGT pipeline mitk::TrackingDevice::Pointer trackingDevice = m_TrackingDevice; trackingDevice->SetData(m_TrackingDeviceData); //set device to rotation mode transposed becaus we are working with VNL style quaternions if(m_InverseMode) {trackingDevice->SetRotationMode(mitk::TrackingDevice::RotationTransposed);} //Get Tracking Volume Data mitk::TrackingDeviceData data = m_TrackingDeviceData; mitk::ProgressBar::GetInstance()->Progress(); //Create Navigation Data Source with the factory class mitk::TrackingDeviceSourceConfigurator::Pointer myTrackingDeviceSourceFactory = mitk::TrackingDeviceSourceConfigurator::New(m_NavigationToolStorage,trackingDevice); m_TrackingDeviceSource = myTrackingDeviceSourceFactory->CreateTrackingDeviceSource(m_ToolVisualizationFilter); mitk::ProgressBar::GetInstance()->Progress(); if ( m_TrackingDeviceSource.IsNull() ) { message = std::string("Cannot connect to device: ") + myTrackingDeviceSourceFactory->GetErrorMessage(); emit ConnectDeviceFinished(false,QString(message.c_str())); return; } //set filter to rotation mode transposed becaus we are working with VNL style quaternions if(m_InverseMode) m_ToolVisualizationFilter->SetRotationMode(mitk::NavigationDataObjectVisualizationFilter::RotationTransposed); //First check if the created object is valid if (m_TrackingDeviceSource.IsNull()) { message = myTrackingDeviceSourceFactory->GetErrorMessage(); emit ConnectDeviceFinished(false,QString(message.c_str())); return; } MITK_INFO << "Number of tools: " << m_TrackingDeviceSource->GetNumberOfOutputs(); mitk::ProgressBar::GetInstance()->Progress(); //The tools are maybe reordered after initialization, e.g. in case of auto-detected tools of NDI Aurora mitk::NavigationToolStorage::Pointer toolsInNewOrder = myTrackingDeviceSourceFactory->GetUpdatedNavigationToolStorage(); if ((toolsInNewOrder.IsNotNull()) && (toolsInNewOrder->GetToolCount() > 0)) { //so delete the old tools in wrong order and add them in the right order //we cannot simply replace the tool storage because the new storage is //not correctly initialized with the right data storage m_NavigationToolStorage->DeleteAllTools(); for (int i=0; i < toolsInNewOrder->GetToolCount(); i++) {m_NavigationToolStorage->AddTool(toolsInNewOrder->GetTool(i));} } mitk::ProgressBar::GetInstance()->Progress(); //connect to device try { m_TrackingDeviceSource->Connect(); mitk::ProgressBar::GetInstance()->Progress(); //Microservice registration: m_TrackingDeviceSource->RegisterAsMicroservice(); m_NavigationToolStorage->UnRegisterMicroservice(); m_NavigationToolStorage->RegisterAsMicroservice(m_TrackingDeviceSource->GetMicroserviceID()); m_NavigationToolStorage->LockStorage(); } catch (...) //todo: change to mitk::IGTException { message = "Error on connecting the tracking device."; emit ConnectDeviceFinished(false,QString(message.c_str())); return; } emit ConnectDeviceFinished(true,QString(message.c_str())); mitk::ProgressBar::GetInstance()->Progress(10); } void QmitkMITKIGTTrackingToolboxViewWorker::StartTracking() { QString errorMessage = ""; try { m_TrackingDeviceSource->StartTracking(); } catch (...) //todo: change to mitk::IGTException { errorMessage += "Error while starting the tracking device!"; emit StartTrackingFinished(false,errorMessage); return; } + //remember the original colors of the tools + m_OriginalColors = std::map(); + for(int i=0; im_NavigationToolStorage->GetToolCount(); i++) + { + mitk::DataNode::Pointer currentToolNode = m_NavigationToolStorage->GetTool(i)->GetDataNode(); + float c[3]; + currentToolNode->GetColor(c); + mitk::Color color; + color.SetRed(c[0]); + color.SetGreen(c[1]); + color.SetBlue(c[2]); + m_OriginalColors[currentToolNode] = color; + } + emit StartTrackingFinished(true,errorMessage); } void QmitkMITKIGTTrackingToolboxViewWorker::StopTracking() { + //stop tracking try { m_TrackingDeviceSource->StopTracking(); } catch(mitk::Exception& e) { emit StopTrackingFinished(false, e.GetDescription()); } + + //restore the original colors of the tools + for(int i=0; im_NavigationToolStorage->GetToolCount(); i++) + { + mitk::DataNode::Pointer currentToolNode = m_NavigationToolStorage->GetTool(i)->GetDataNode(); + if (m_OriginalColors.find(currentToolNode) == m_OriginalColors.end()) + {MITK_WARN << "Cannot restore original color of tool " << m_NavigationToolStorage->GetTool(i)->GetToolName();} + else + {currentToolNode->SetColor(m_OriginalColors[currentToolNode]);} + } + + //emit signal emit StopTrackingFinished(true, ""); } void QmitkMITKIGTTrackingToolboxViewWorker::DisconnectDevice() { try { if (m_TrackingDeviceSource->IsTracking()) {m_TrackingDeviceSource->StopTracking();} m_TrackingDeviceSource->Disconnect(); m_TrackingDeviceSource->UnRegisterMicroservice(); m_NavigationToolStorage->UnLockStorage(); } catch(mitk::Exception& e) { emit DisconnectDeviceFinished(false, e.GetDescription()); } emit DisconnectDeviceFinished(true, ""); } diff --git a/Plugins/org.mitk.gui.qt.igttracking/src/internal/QmitkMITKIGTTrackingToolboxView.h b/Plugins/org.mitk.gui.qt.igttracking/src/internal/QmitkMITKIGTTrackingToolboxView.h index b4804243c0..037df1aaa8 100644 --- a/Plugins/org.mitk.gui.qt.igttracking/src/internal/QmitkMITKIGTTrackingToolboxView.h +++ b/Plugins/org.mitk.gui.qt.igttracking/src/internal/QmitkMITKIGTTrackingToolboxView.h @@ -1,257 +1,260 @@ /*=================================================================== 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. ===================================================================*/ #ifndef QmitkMITKIGTTrackingToolboxView_h #define QmitkMITKIGTTrackingToolboxView_h #include #include #include "ui_QmitkMITKIGTTrackingToolboxViewControls.h" //mitk headers #include #include #include #include //QT headers #include class QmitkMITKIGTTrackingToolboxViewWorker; /*! \brief QmitkMITKIGTTrackingToolboxView This is the view of the bundle IGT Tracking Toolbox. The IGT Tracking Toolbox can be used to access tracking devices with MITK-IGT. The Tracking Toolbox can be used to log tracking data in XML or CSV format for measurement purposes. The Tracking Toolbox further allows for visualization of tools with given surfaces in combination with the NaviagtionToolManager. \sa QmitkFunctionality \ingroup Functionalities */ class QmitkMITKIGTTrackingToolboxView : public QmitkFunctionality { // 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; QmitkMITKIGTTrackingToolboxView(); virtual ~QmitkMITKIGTTrackingToolboxView(); virtual void CreateQtPartControl(QWidget *parent); virtual void StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget); virtual void StdMultiWidgetNotAvailable(); protected slots: /** @brief changes name of the filename when switching fileextension by radio button */ void OnToggleFileExtension(); /** @brief This slot is called if the user wants to load a new tool file. A new window opens where the user can choose a file. If the chosen file is corrupt or not valid the user gets an error message. If the file was loaded successfully the tools are show in the tool status widget. */ void OnLoadTools(); /** @brief This slot connects to the device. In status "connected" configuration of the device is disabled. */ void OnConnect(); /** @brief This slot disconnects from the device. */ void OnDisconnect(); /** @brief This slot tries to start tracking with the current device. If start tracking fails the user gets an error message and tracking stays off.*/ void OnStartTracking(); /** @brief This slot stops tracking. If tracking is not strated it does nothing.*/ void OnStopTracking(); /** @brief This slot is called if the user want's to choose a file name for logging. A new windows to navigate through the file system and choose a file opens.*/ void OnChooseFileClicked(); /** @brief This slot starts logging. Logging is only possible if a device is tracking. If not the logging mechanism start when the start tracking is called.*/ void StartLogging(); /** @brief This slot stops logging. If logging is not running it does nothing.*/ void StopLogging(); /** @brief This slot enables / disables UI elements depending on the tracking device after a device is changed.*/ void OnTrackingDeviceChanged(); /** @brief This slot selects the Tracking Volume appropriate for a given model */ void OnTrackingVolumeChanged(QString qstr); /** @brief Shows or hides the tracking volume according to the checkboxe's state */ void OnShowTrackingVolumeChanged(); /** @brief This slot auto detects tools of a NDI Aurora tracking device. If tools where found they will be stored internally as a tool storage. The user is also asked if he wants to save this tool storage to load it later. Only call it if a Aurora device was configured because other devices don't support auto detection.*/ void OnAutoDetectTools(); /** @brief Slot for tracking timer. The timer updates the IGT pipline and also the logging filter if logging is activated.*/ void UpdateTrackingTimer(); /** @brief Resets the Tracking Tools: this means all tools are removed. */ void OnResetTools(); /** @brief Opens a dialog where a new navigation tool can be created. */ void OnAddSingleTool(); /** @brief This slot is called if the user finishes the creation of a new tool. */ void OnAddSingleToolFinished(); /** @brief This slot is called if the user cancels the creation of a new tool. */ void OnAddSingleToolCanceled(); protected slots: //help slots for enable/disable buttons void DisableLoggingButtons(); void EnableLoggingButtons(); void DisableOptionsButtons(); void EnableOptionsButtons(); void EnableTrackingConfigurationButtons(); void DisableTrackingConfigurationButtons(); void EnableTrackingControls(); void DisableTrackingControls(); //slots for worker thread void OnAutoDetectToolsFinished(bool success, QString errorMessage); void OnConnectFinished(bool success, QString errorMessage); void OnStartTrackingFinished(bool success, QString errorMessage); void OnStopTrackingFinished(bool success, QString errorMessage); void OnDisconnectFinished(bool success, QString errorMessage); protected: Ui::QmitkMITKIGTTrackingToolboxViewControls* m_Controls; QmitkStdMultiWidget* m_MultiWidget; bool m_tracking; ///> bool which is true if tracking is running, false if not bool m_logging; ///> bool which is true if logging is running, false if not int m_loggedFrames; ///> stores the current number of logged frames if logging is on mitk::NavigationToolStorage::Pointer m_toolStorage; ///>stores the loaded tools mitk::DataNode::Pointer m_TrackingVolumeNode; ///>holds the data node of the tracking volume if volume is visualized bool lastTrackingVolumeState; ///>temporary holds the state of the tracking volume (activated/not activated) during some methods QString m_ToolStorageFilename; ///>stores the filename of the current tool storage /** @brief Shows a message box with the text given as parameter. */ void MessageBox(std::string s); /** @brief reinits the view globally. */ void GlobalReinit(); //members for the filter pipeline mitk::TrackingDeviceSource::Pointer m_TrackingDeviceSource; ///> member for the source of the IGT pipeline mitk::TrackingDeviceData m_TrackingDeviceData; ///> stores the tracking device data as long as this is not handled by the tracking device configuration widget mitk::NavigationDataObjectVisualizationFilter::Pointer m_ToolVisualizationFilter; ///> holds the tool visualization filter (second filter of the IGT pipeline) mitk::NavigationDataRecorder::Pointer m_loggingFilter; ///> holds the logging filter if logging is on (third filter of the IGT pipeline) /** @brief This timer updates the IGT pipline and also the logging filter if logging is activated.*/ QTimer* m_TrackingTimer; /** Replaces the current navigation tool storage which is stored in m_toolStorage. * Basically handles the microservice stuff: unregisteres the old storage, then * replaces the storage and registers the new one. */ void ReplaceCurrentToolStorage(mitk::NavigationToolStorage::Pointer newStorage, std::string newStorageName); /** * \brief Stores the properties of some QWidgets (and the tool storage file name) to QSettings. */ void StoreUISettings(); /** * \brief Loads the properties of some QWidgets (and the tool storage file name) from QSettings. */ void LoadUISettings(); //members for worker thread QThread* m_WorkerThread; QmitkMITKIGTTrackingToolboxViewWorker* m_Worker; }; /** * Worker thread class for this view. */ class QmitkMITKIGTTrackingToolboxViewWorker : public QObject { Q_OBJECT public: enum WorkerMethod{ eAutoDetectTools = 0, eConnectDevice = 1, eStartTracking = 2, eStopTracking = 3, eDisconnectDevice = 4 }; void SetWorkerMethod(WorkerMethod w); void SetTrackingDevice(mitk::TrackingDevice::Pointer t); void SetDataStorage(mitk::DataStorage::Pointer d); void SetInverseMode(bool mode); void SetTrackingDeviceData(mitk::TrackingDeviceData d); void SetNavigationToolStorage(mitk::NavigationToolStorage::Pointer n); itkGetMacro(NavigationToolStorage,mitk::NavigationToolStorage::Pointer); itkGetMacro(TrackingDeviceSource,mitk::TrackingDeviceSource::Pointer); itkGetMacro(TrackingDeviceData,mitk::TrackingDeviceData); itkGetMacro(ToolVisualizationFilter,mitk::NavigationDataObjectVisualizationFilter::Pointer); public slots: void ThreadFunc(); signals: void AutoDetectToolsFinished(bool success, QString errorMessage); void ConnectDeviceFinished(bool success, QString errorMessage); void StartTrackingFinished(bool success, QString errorMessage); void StopTrackingFinished(bool success, QString errorMessage); void DisconnectDeviceFinished(bool success, QString errorMessage); protected: mitk::TrackingDevice::Pointer m_TrackingDevice; WorkerMethod m_WorkerMethod; mitk::DataStorage::Pointer m_DataStorage; mitk::NavigationToolStorage::Pointer m_NavigationToolStorage; //members for the filter pipeline which is created in the worker thread during ConnectDevice() mitk::TrackingDeviceSource::Pointer m_TrackingDeviceSource; ///> member for the source of the IGT pipeline mitk::TrackingDeviceData m_TrackingDeviceData; ///> stores the tracking device data as long as this is not handled by the tracking device configuration widget mitk::NavigationDataObjectVisualizationFilter::Pointer m_ToolVisualizationFilter; ///> holds the tool visualization filter (second filter of the IGT pipeline) bool m_InverseMode; + //stores the original colors of the tracking tools + std::map m_OriginalColors; + void AutoDetectTools(); void ConnectDevice(); void StartTracking(); void StopTracking(); void DisconnectDevice(); }; #endif // _QMITKMITKIGTTRACKINGTOOLBOXVIEW_H_INCLUDED diff --git a/Plugins/org.mitk.gui.qt.ultrasound/src/internal/UltrasoundSupport.cpp b/Plugins/org.mitk.gui.qt.ultrasound/src/internal/UltrasoundSupport.cpp index 41d1170675..92495afcb1 100644 --- a/Plugins/org.mitk.gui.qt.ultrasound/src/internal/UltrasoundSupport.cpp +++ b/Plugins/org.mitk.gui.qt.ultrasound/src/internal/UltrasoundSupport.cpp @@ -1,351 +1,343 @@ /*=================================================================== 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 //Mitk #include #include #include #include #include // Qmitk #include "UltrasoundSupport.h" #include // Qt #include // Ultrasound #include "mitkUSDevice.h" #include "QmitkUSAbstractCustomWidget.h" #include #include #include "usServiceReference.h" #include "internal/org_mitk_gui_qt_ultrasound_Activator.h" const std::string UltrasoundSupport::VIEW_ID = "org.mitk.views.ultrasoundsupport"; void UltrasoundSupport::SetFocus() { } void UltrasoundSupport::CreateQtPartControl( QWidget *parent ) { m_Timer = new QTimer(this); // create GUI widgets from the Qt Designer's .ui file m_Controls.setupUi( parent ); connect( m_Controls.m_DeviceManagerWidget, SIGNAL(NewDeviceButtonClicked()), this, SLOT(OnClickedAddNewDevice()) ); // Change Widget Visibilities connect( m_Controls.m_DeviceManagerWidget, SIGNAL(NewDeviceButtonClicked()), this->m_Controls.m_NewVideoDeviceWidget, SLOT(CreateNewDevice()) ); // Init NewDeviceWidget connect( m_Controls.m_ActiveVideoDevices, SIGNAL(ServiceSelectionChanged(us::ServiceReferenceU)), this, SLOT(OnChangedActiveDevice()) ); connect( m_Controls.m_ShowImageStream, SIGNAL(clicked()), this, SLOT(OnChangedActiveDevice()) ); connect( m_Controls.m_NewVideoDeviceWidget, SIGNAL(Finished()), this, SLOT(OnNewDeviceWidgetDone()) ); // After NewDeviceWidget finished editing connect( m_Controls.m_FrameRate, SIGNAL(valueChanged(int)), this, SLOT(OnChangedFramerateLimit(int)) ); connect( m_Controls.m_FreezeButton, SIGNAL(clicked()), this, SLOT(OnClickedFreezeButton()) ); connect( m_Timer, SIGNAL(timeout()), this, SLOT(DisplayImage())); // Initializations m_Controls.m_NewVideoDeviceWidget->setVisible(false); std::string filter = "(&(" + us::ServiceConstants::OBJECTCLASS() + "=" + "org.mitk.services.UltrasoundDevice)(" + mitk::USDevice::GetPropertyKeys().US_PROPKEY_ISACTIVE + "=true))"; m_Controls.m_ActiveVideoDevices->Initialize( mitk::USDevice::GetPropertyKeys().US_PROPKEY_LABEL ,filter); m_Controls.m_ActiveVideoDevices->SetAutomaticallySelectFirstEntry(true); +m_FrameCounter = 0; // Create Node for US Stream if (m_Node.IsNull()) { m_Node = mitk::DataNode::New(); m_Node->SetName("US Support Viewing Stream"); //create a dummy image (gray values 0..255) for correct initialization of level window, etc. mitk::Image::Pointer dummyImage = mitk::ImageGenerator::GenerateRandomImage(100, 100, 1, 1, 1, 1, 1, 255,0); m_Node->SetData(dummyImage); m_OldGeometry = dynamic_cast(dummyImage->GetGeometry()); } m_Controls.tabWidget->setTabEnabled(1, false); } void UltrasoundSupport::OnClickedAddNewDevice() { m_Controls.m_NewVideoDeviceWidget->setVisible(true); m_Controls.m_DeviceManagerWidget->setVisible(false); m_Controls.m_Headline->setText("Add New Video Device:"); m_Controls.m_WidgetActiveDevices->setVisible(false); } void UltrasoundSupport::DisplayImage() { //Update device m_Device->Modified(); m_Device->Update(); -//Update data node -mitk::Image::Pointer curOutput = m_Device->GetOutput(); -m_Node->SetData(curOutput); - -// if the geometry changed: make a reinit on the ultrasound image -if(!mitk::Equal(m_OldGeometry.GetPointer(),curOutput->GetGeometry(),0.0001,false)) -{ -mitk::IRenderWindowPart* renderWindow = this->GetRenderWindowPart(); -if ( renderWindow != NULL && curOutput->GetTimeGeometry()->IsValid() ) -{ -renderWindow->GetRenderingManager()->InitializeViews( -curOutput->GetGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true ); -renderWindow->GetRenderingManager()->RequestUpdateAll(); -} -m_OldGeometry = dynamic_cast(curOutput->GetGeometry()); -} - //Only update the view if the image is shown if(m_Controls.m_ShowImageStream->isChecked()) { -this->RequestRenderWindowUpdate(); -if ( curOutput->GetDimension() > 1 -&& (curOutput->GetDimension(0) != m_CurrentImageWidth -|| curOutput->GetDimension(1) != m_CurrentImageHeight) ) -{ -// make a reinit on the ultrasound image -mitk::IRenderWindowPart* renderWindow = this->GetRenderWindowPart(); -if ( renderWindow != NULL && curOutput->GetTimeGeometry()->IsValid() ) -{ -renderWindow->GetRenderingManager()->InitializeViews( -curOutput->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true ); -renderWindow->GetRenderingManager()->RequestUpdateAll(); -} + //Update data node + mitk::Image::Pointer curOutput = m_Device->GetOutput(); + m_Node->SetData(curOutput); -m_CurrentImageWidth = curOutput->GetDimension(0); -m_CurrentImageHeight = curOutput->GetDimension(1); -} + // if the geometry changed: reinitialize the ultrasound image + if(!mitk::Equal(m_OldGeometry.GetPointer(),curOutput->GetGeometry(),0.0001,false)) + { + mitk::IRenderWindowPart* renderWindow = this->GetRenderWindowPart(); + if ( (renderWindow != NULL) && (curOutput->GetTimeGeometry()->IsValid()) && (m_Controls.m_ShowImageStream->isChecked()) ) + { + renderWindow->GetRenderingManager()->InitializeViews( + curOutput->GetGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true ); + renderWindow->GetRenderingManager()->RequestUpdateAll(); + } + m_CurrentImageWidth = curOutput->GetDimension(0); + m_CurrentImageHeight = curOutput->GetDimension(1); + m_OldGeometry = dynamic_cast(curOutput->GetGeometry()); + } + //if not: only update the view + else + { + this->RequestRenderWindowUpdate(); + } } //Update frame counter m_FrameCounter ++; -if (m_FrameCounter == 10) -{ -int nMilliseconds = m_Clock.restart(); -int fps = 10000.0f / (nMilliseconds ); -m_Controls.m_FramerateLabel->setText("Current Framerate: "+ QString::number(fps) +" FPS"); -m_FrameCounter = 0; -} +if (m_FrameCounter >= 10) + { + int nMilliseconds = m_Clock.restart(); + int fps = 10000.0f / (nMilliseconds ); + m_Controls.m_FramerateLabel->setText("Current Framerate: "+ QString::number(fps) +" FPS"); + m_FrameCounter = 0; + } } void UltrasoundSupport::OnChangedFramerateLimit(int value) { +m_Timer->stop(); m_Timer->setInterval(1000 / value); +m_Timer->start(); } void UltrasoundSupport::OnClickedFreezeButton() { if ( m_Device.IsNull() ) { MITK_WARN("UltrasoundSupport") << "Freeze button clicked though no device is selected."; return; } if ( m_Device->GetIsFreezed() ) { m_Device->SetIsFreezed(false); m_Controls.m_FreezeButton->setText("Freeze"); } else { m_Device->SetIsFreezed(true); m_Controls.m_FreezeButton->setText("Start Viewing Again"); } } void UltrasoundSupport::OnChangedActiveDevice() { //clean up and stop timer m_Timer->stop(); this->RemoveControlWidgets(); this->GetDataStorage()->Remove(m_Node); m_Node->ReleaseData(); //get current device, abort if it is invalid m_Device = m_Controls.m_ActiveVideoDevices->GetSelectedService(); if (m_Device.IsNull()) { MITK_WARN << "Selected device is not valid, aborting"; m_Controls.tabWidget->setTabEnabled(1, false); return; } //create the widgets for this device and enable the widget tab this->CreateControlWidgets(); m_Controls.tabWidget->setTabEnabled(1, true); //show node if the option is enabled if(m_Controls.m_ShowImageStream->isChecked()) {this->GetDataStorage()->Add(m_Node);} //start timer int interval = (1000 / m_Controls.m_FrameRate->value()); m_Timer->setInterval(interval); m_Timer->start(); } void UltrasoundSupport::OnNewDeviceWidgetDone() { m_Controls.m_NewVideoDeviceWidget->setVisible(false); m_Controls.m_DeviceManagerWidget->setVisible(true); m_Controls.m_Headline->setText("Ultrasound Devices:"); m_Controls.m_WidgetActiveDevices->setVisible(true); } void UltrasoundSupport::CreateControlWidgets() { m_ControlProbesWidget = new QmitkUSControlsProbesWidget(m_Device->GetControlInterfaceProbes(), m_Controls.m_ToolBoxControlWidgets); m_Controls.probesWidgetContainer->addWidget(m_ControlProbesWidget); // create b mode widget for current device m_ControlBModeWidget = new QmitkUSControlsBModeWidget(m_Device->GetControlInterfaceBMode(), m_Controls.m_ToolBoxControlWidgets); m_Controls.m_ToolBoxControlWidgets->addItem(m_ControlBModeWidget, "B Mode Controls"); if ( ! m_Device->GetControlInterfaceBMode() ) { m_Controls.m_ToolBoxControlWidgets->setItemEnabled(m_Controls.m_ToolBoxControlWidgets->count()-1, false); } // create doppler widget for current device m_ControlDopplerWidget = new QmitkUSControlsDopplerWidget(m_Device->GetControlInterfaceDoppler(), m_Controls.m_ToolBoxControlWidgets); m_Controls.m_ToolBoxControlWidgets->addItem(m_ControlDopplerWidget, "Doppler Controls"); if ( ! m_Device->GetControlInterfaceDoppler() ) { m_Controls.m_ToolBoxControlWidgets->setItemEnabled(m_Controls.m_ToolBoxControlWidgets->count()-1, false); } ctkPluginContext* pluginContext = mitk::PluginActivator::GetContext(); if ( pluginContext ) { std::string filter = "(ork.mitk.services.UltrasoundCustomWidget.deviceClass=" + m_Device->GetDeviceClass() + ")"; QString interfaceName ( us_service_interface_iid() ); m_CustomWidgetServiceReference = pluginContext->getServiceReferences(interfaceName, QString::fromStdString(filter)); if (m_CustomWidgetServiceReference.size() > 0) { m_ControlCustomWidget = pluginContext->getService (m_CustomWidgetServiceReference.at(0))->CloneForQt(m_Controls.tab2); m_ControlCustomWidget->SetDevice(m_Device); m_Controls.m_ToolBoxControlWidgets->addItem(m_ControlCustomWidget, "Custom Controls"); } else { m_Controls.m_ToolBoxControlWidgets->addItem(new QWidget(m_Controls.m_ToolBoxControlWidgets), "Custom Controls"); m_Controls.m_ToolBoxControlWidgets->setItemEnabled(m_Controls.m_ToolBoxControlWidgets->count()-1, false); } } // select first enabled control widget for ( int n = 0; n < m_Controls.m_ToolBoxControlWidgets->count(); ++n) { if ( m_Controls.m_ToolBoxControlWidgets->isItemEnabled(n) ) { m_Controls.m_ToolBoxControlWidgets->setCurrentIndex(n); break; } } } void UltrasoundSupport::RemoveControlWidgets() { if(!m_ControlProbesWidget) {return;} //widgets do not exist... nothing to do // remove all control widgets from the tool box widget while (m_Controls.m_ToolBoxControlWidgets->count() > 0) { m_Controls.m_ToolBoxControlWidgets->removeItem(0); } // remove probes widget (which is not part of the tool box widget) m_Controls.probesWidgetContainer->removeWidget(m_ControlProbesWidget); delete m_ControlProbesWidget; m_ControlProbesWidget = 0; delete m_ControlBModeWidget; m_ControlBModeWidget = 0; delete m_ControlDopplerWidget; m_ControlDopplerWidget = 0; // delete custom widget if it is present if ( m_ControlCustomWidget ) { ctkPluginContext* pluginContext = mitk::PluginActivator::GetContext(); delete m_ControlCustomWidget; m_ControlCustomWidget = 0; if ( m_CustomWidgetServiceReference.size() > 0 ) { pluginContext->ungetService(m_CustomWidgetServiceReference.at(0)); } } } void UltrasoundSupport::OnDeciveServiceEvent(const ctkServiceEvent event) { if ( m_Device.IsNull() || event.getType() != us::ServiceEvent::MODIFIED ) { return; } ctkServiceReference service = event.getServiceReference(); if ( m_Device->GetManufacturer() != service.getProperty(QString::fromStdString(mitk::USDevice::GetPropertyKeys().US_PROPKEY_MANUFACTURER)).toString().toStdString() && m_Device->GetName() != service.getProperty(QString::fromStdString(mitk::USDevice::GetPropertyKeys().US_PROPKEY_NAME)).toString().toStdString() ) { return; } if ( ! m_Device->GetIsActive() && m_Timer->isActive() ) { m_Timer->stop(); } if ( m_CurrentDynamicRange != service.getProperty(QString::fromStdString(mitk::USDevice::GetPropertyKeys().US_PROPKEY_BMODE_DYNAMIC_RANGE)).toDouble() ) { m_CurrentDynamicRange = service.getProperty(QString::fromStdString(mitk::USDevice::GetPropertyKeys().US_PROPKEY_BMODE_DYNAMIC_RANGE)).toDouble(); // update level window for the current dynamic range mitk::LevelWindow levelWindow; m_Node->GetLevelWindow(levelWindow); levelWindow.SetAuto(m_Image, true, true); m_Node->SetLevelWindow(levelWindow); } } UltrasoundSupport::UltrasoundSupport() : m_ControlCustomWidget(0), m_ControlBModeWidget(0), m_ControlProbesWidget(0), m_ImageAlreadySetToNode(false), m_CurrentImageWidth(0), m_CurrentImageHeight(0) { ctkPluginContext* pluginContext = mitk::PluginActivator::GetContext(); if ( pluginContext ) { // to be notified about service event of an USDevice pluginContext->connectServiceListener(this, "OnDeciveServiceEvent", QString::fromStdString("(" + us::ServiceConstants::OBJECTCLASS() + "=" + us_service_interface_iid() + ")")); } } UltrasoundSupport::~UltrasoundSupport() { }