diff --git a/Modules/IGT/TrackingDevices/mitkClaronInterface.h b/Modules/IGT/TrackingDevices/mitkClaronInterface.h index 40e8531e77..1840c8ad83 100644 --- a/Modules/IGT/TrackingDevices/mitkClaronInterface.h +++ b/Modules/IGT/TrackingDevices/mitkClaronInterface.h @@ -1,145 +1,145 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef MITKCLARONINTERFACE_H_HEADER_INCLUDED_ #define MITKCLARONINTERFACE_H_HEADER_INCLUDED_ #define MTC(func) {int r = func; if (r!=mtOK) printf("MTC error: %s\n",MTLastErrorString()); }; #include #include #include #include "mitkCommon.h" #include #include #ifdef _WIN64 //Defined for applications for Win64. -typedef long mtHandle; +typedef long long mtHandle; #else typedef int mtHandle; #endif namespace mitk { typedef int claronToolHandle; /** Documentation: * \brief An object of this class represents the interface to the MicronTracker. The methods of this class * are calling the c-functions which are provided by the MTC-library. If the MicronTracker is not in * use, which means the CMake-variable "MITK_USE_MICRON_TRACKER" is set to OFF, this class is replaced * by a stub class called "ClaronInterfaceStub". * \ingroup IGT */ class MITKIGT_EXPORT ClaronInterface : public itk::Object { public: mitkClassMacroItkParent(ClaronInterface,itk::Object); itkFactorylessNewMacro(Self); itkCloneMacro(Self) /** * \brief Initialization of claroninterface. * \param calibrationDir The directory where the device can find the camera calibration file. * \param toolFilesDir The directory for the tool files. */ void Initialize(std::string calibrationDir, std::string toolFilesDir); /** * \brief Opens the connection to the device and makes it ready to track tools. * \return Returns true if there is a connection to the device and the device is ready to track tools, false if not. */ bool StartTracking(); /** * \brief Clears all resources. After this method have been called the system isn't ready to track any longer. * \return Returns true if the operation was succesful, false if not. */ bool StopTracking(); /** * \return Returns all tools which have been detected at the last frame grab. */ std::vector GetAllActiveTools(); /** * \return Returns the position of the tooltip. If no tooltip is defined the Method returns the position of the tool. */ std::vector GetTipPosition(claronToolHandle c); /** * \return Returns the quarternions of the tooltip. If no tooltip is defined the Method returns the quarternions of the tool. */ std::vector GetTipQuaternions(claronToolHandle c); /** * \return Returns the position of the tool */ std::vector GetPosition(claronToolHandle c); /** * \return Returns the quaternion of the tool. */ std::vector GetQuaternions(claronToolHandle c); /** * \return Returns the name of the tool. This name is given by the calibration file. * \param c The handle of the tool, which name should be given back. */ const char* GetName(claronToolHandle c); /** * \brief Grabs a frame from the camera. */ void GrabFrame(); /** * \return Returns wether the tracking device is tracking or not. */ bool IsTracking(); /** * \return Returns wether the MicronTracker is installed (means wether the C-Make-Variable "MITK_USE_MICRON_TRACKER" is set ON), * so returns true in this case. This is because the class mitkClaronInterfaceStub, in which the same Method returns false * is used otherways. */ bool IsMicronTrackerInstalled(); protected: /** * \brief standard constructor */ ClaronInterface(); /** * \brief standard destructor */ ~ClaronInterface() override; /** \brief Variable is true if the device is tracking at the moment, false if not.*/ bool isTracking; /** \brief Variable which holds the directory which should contain the file BumbleBee_6400420.calib. This directory is needed by the MTC library.*/ char calibrationDir[512]; /** \brief Variable which holds a directory with some tool files in it. All this tools are trackable when the path is given to the MTC library.*/ char markerDir[512]; //Some handles to communicate with the MTC library. mtHandle IdentifiedMarkers; mtHandle PoseXf; mtHandle CurrCamera; mtHandle IdentifyingCamera; //------------------------------------------------ }; }//mitk #endif diff --git a/Modules/IGT/TrackingDevices/mitkPolhemusTool.h b/Modules/IGT/TrackingDevices/mitkPolhemusTool.h index b16589a3b5..9fa679e67c 100644 --- a/Modules/IGT/TrackingDevices/mitkPolhemusTool.h +++ b/Modules/IGT/TrackingDevices/mitkPolhemusTool.h @@ -1,84 +1,83 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef MITKPolhemusTOOL_H_HEADER_INCLUDED_ #define MITKPolhemusTOOL_H_HEADER_INCLUDED_ #include #include -#include namespace mitk { class PolhemusTrackingDevice; /** Documentation: * \brief An object of this class represents a tool of a Polhemus tracking device. * A tool has to be added to a tracking device which will then * continuously update the tool coordinates. * \ingroup IGT */ class MITKIGT_EXPORT PolhemusTool : public TrackingTool { public: friend class PolhemusTrackingDevice; mitkClassMacro(PolhemusTool, TrackingTool); enum DistortionLevel { UNDEFINED, ///< Distortion level is not determined. NO_DISTORTION, ///< System operational with a good quality magnetic signal. MINOR_DISTORTION, ///< System operational with a marginal magnetic signal. SIGNIFICANT_DISTORTION ///< System operational with a poor magnetic signal. }; /** * \brief Sets the port of the tool. (e.g. 1 for port "SENS 1" etc.) */ virtual void SetToolPort(int _ToolPort); /** * \brief Sets the port of the tool. (e.g. 1 for port "SENS 1" etc.) */ virtual int GetToolPort(); /** * \brief Sets the distortion level by mapping the integer value (read from the response frame) to the corresponding enumeration literal. * * According to the Polhemus Liberty documentation: * - 0 means system operational with a good quality magnetic signal. No distortion. * - 1 means system operational with a marginal magnetic signal. Minor distortion. * - 2 means system operational with a poor magnetic signal. Significant distortion. * * \param level The distortion level represented as 0, 1 or 2. */ void SetDistortionLevel(const int level); /** * \brief Returns the distortion level. * \return The distortion level. UNDEFINED, if distortion level is not determined. */ DistortionLevel GetDistortionLevel() const; protected: itkFactorylessNewMacro(Self); itkCloneMacro(Self) PolhemusTool(); virtual ~PolhemusTool(); //This is the port, on which the tool is connected. It is identical with the "ToolIdentifier" set on NavigationDataTools. //If tool is connected on port "SENS 2", the m_ToolPort is 2 etc. int m_ToolPort; DistortionLevel m_DistortionLevel; }; }//mitk #endif // MITKPolhemusTOOL_H_HEADER_INCLUDED_ diff --git a/Modules/IGT/TrackingDevices/mitkPolhemusTrackerTypeInformation.cpp b/Modules/IGT/TrackingDevices/mitkPolhemusTrackerTypeInformation.cpp index 1d8a9374b1..94dc4bc874 100644 --- a/Modules/IGT/TrackingDevices/mitkPolhemusTrackerTypeInformation.cpp +++ b/Modules/IGT/TrackingDevices/mitkPolhemusTrackerTypeInformation.cpp @@ -1,66 +1,66 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkPolhemusTrackerTypeInformation.h" #include "mitkPolhemusTrackingDevice.h" namespace mitk { std::string PolhemusTrackerTypeInformation::GetTrackingDeviceName() { return "Polhemus tracker"; } TrackingDeviceData PolhemusTrackerTypeInformation::GetDeviceDataPolhemusTrackerLiberty() { TrackingDeviceData data = { PolhemusTrackerTypeInformation::GetTrackingDeviceName(), "Polhemus Liberty Tracker", "cube", "X" }; return data; } PolhemusTrackerTypeInformation::PolhemusTrackerTypeInformation() { m_DeviceName = PolhemusTrackerTypeInformation::GetTrackingDeviceName(); m_TrackingDeviceData.push_back(GetDeviceDataPolhemusTrackerLiberty()); } PolhemusTrackerTypeInformation::~PolhemusTrackerTypeInformation() { } mitk::TrackingDeviceSource::Pointer PolhemusTrackerTypeInformation::CreateTrackingDeviceSource( mitk::TrackingDevice::Pointer trackingDevice, mitk::NavigationToolStorage::Pointer navigationTools, std::string* errorMessage, std::vector* toolCorrespondencesInToolStorage) { mitk::TrackingDeviceSource::Pointer returnValue = mitk::TrackingDeviceSource::New(); mitk::PolhemusTrackingDevice::Pointer thisDevice = dynamic_cast(trackingDevice.GetPointer()); *toolCorrespondencesInToolStorage = std::vector(); //add the tools to the tracking device for (unsigned int i = 0; i < navigationTools->GetToolCount(); i++) { mitk::NavigationTool::Pointer thisNavigationTool = navigationTools->GetTool(i); toolCorrespondencesInToolStorage->push_back(i); bool toolAddSuccess = thisDevice->AddTool(thisNavigationTool->GetToolName().c_str(), std::stoi(thisNavigationTool->GetIdentifier())); if (!toolAddSuccess) { //todo error handling errorMessage->append("Can't add tool, is the toolfile valid?"); - return NULL; + return nullptr; } thisDevice->GetTool(i)->SetToolTipPosition(thisNavigationTool->GetToolTipPosition(), thisNavigationTool->GetToolAxisOrientation()); } returnValue->SetTrackingDevice(thisDevice); return returnValue; } } diff --git a/Modules/IGT/TrackingDevices/mitkPolhemusTrackingDevice.cpp b/Modules/IGT/TrackingDevices/mitkPolhemusTrackingDevice.cpp index 628637fc3d..156213927c 100644 --- a/Modules/IGT/TrackingDevices/mitkPolhemusTrackingDevice.cpp +++ b/Modules/IGT/TrackingDevices/mitkPolhemusTrackingDevice.cpp @@ -1,325 +1,304 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkPolhemusTrackingDevice.h" #include "mitkPolhemusTool.h" #include "mitkIGTConfig.h" #include "mitkIGTTimeStamp.h" #include "mitkIGTHardwareException.h" #include #include -#include +#include #include "mitkPolhemusTrackerTypeInformation.h" -typedef itk::MutexLockHolder MutexLockHolder; - mitk::PolhemusTrackingDevice::PolhemusTrackingDevice() : mitk::TrackingDevice() { //set the type of this tracking device this->m_Data = mitk::PolhemusTrackerTypeInformation::GetDeviceDataPolhemusTrackerLiberty(); - - this->m_MultiThreader = itk::MultiThreader::New(); - m_ThreadID = 0; - m_Device = mitk::PolhemusInterface::New(); } mitk::PolhemusTrackingDevice::~PolhemusTrackingDevice() { } bool mitk::PolhemusTrackingDevice::IsDeviceInstalled() { return true; } mitk::TrackingTool* mitk::PolhemusTrackingDevice::AddTool(const char* toolName, int toolPort) { //Only add tool if port isn't already used. for (auto _tool : m_AllTools) { if (_tool->GetToolPort() == toolPort) { MITK_DEBUG << "There is already a tool connected to this port. Returning existing tool"; return _tool; } } mitk::PolhemusTool::Pointer t = mitk::PolhemusTool::New(); t->SetToolName(toolName); t->SetToolPort(toolPort); if (this->InternalAddTool(t) == false) return nullptr; return t.GetPointer(); } bool mitk::PolhemusTrackingDevice::InternalAddTool(PolhemusTool::Pointer tool) { m_AllTools.push_back(tool); return true; } bool mitk::PolhemusTrackingDevice::StartTracking() { bool success = m_Device->StartTracking(); if (success) { mitk::IGTTimeStamp::GetInstance()->Start(this); this->SetState(Tracking); - this->m_StopTrackingMutex->Lock(); + this->m_StopTrackingMutex.lock(); this->m_StopTracking = false; - this->m_StopTrackingMutex->Unlock(); - m_ThreadID = m_MultiThreader->SpawnThread(this->ThreadStartTracking, this); // start a new thread that executes the TrackTools() method - return true; + this->m_StopTrackingMutex.unlock(); + if (m_Thread.joinable()) {m_Thread.detach();} + m_Thread = std::thread(&PolhemusTrackingDevice::ThreadStartTracking, this); // start a new thread that executes the TrackTools() methodreturn true; } else { this->SetState(Ready); mitkThrowException(mitk::IGTHardwareException) << "Error while trying to start the device!"; } return success; } bool mitk::PolhemusTrackingDevice::StopTracking() { m_Device->StopTracking(); return Superclass::StopTracking(); } unsigned int mitk::PolhemusTrackingDevice::GetToolCount() const { return (unsigned int)this->m_AllTools.size(); } mitk::TrackingTool* mitk::PolhemusTrackingDevice::GetTool(unsigned int toolNumber) const { if (toolNumber >= this->GetToolCount()) return nullptr; else return this->m_AllTools[toolNumber]; } bool mitk::PolhemusTrackingDevice::OpenConnection() { //reset everything if (m_Device.IsNull()) { m_Device = mitk::PolhemusInterface::New(); } if (!m_Device->Connect()) //Connect the device, if it fails, throw an error. { MITK_ERROR << "Cannot connect Polhemus device!"; CloseConnection(); return false; } //Ready must be set here, 'cause if tools don't match we need to be able to disconnect. this->SetState(Ready); //check if connected ports of Polhemus matches the tools in the toolStorage. std::vector toolPorts = m_Device->GetToolPorts(); //first, check size. if (this->GetToolCount() != toolPorts.size()) { MITK_ERROR << "Cannot connect device, number of tools in toolstorage doesn't match the number of tools connected to Polhemus device!"; CloseConnection(); return false; } //second, check if toolStorage identifier is included in this port. for (auto _tool : m_AllTools) { if (std::find(toolPorts.begin(), toolPorts.end(), _tool->GetToolPort()) == toolPorts.end()) { MITK_ERROR << "Cannot connect device, tool " << _tool->GetToolPort() << " is not connected to its port."; CloseConnection(); return false; } else { //erase this port to avoid that two tools want to connect to the same port. toolPorts.erase(std::find(toolPorts.begin(), toolPorts.end(), _tool->GetToolPort())); } } m_Device->SetHemisphereTrackingEnabled(m_HemisphereTrackingEnabled); return true; } bool mitk::PolhemusTrackingDevice::CloseConnection() { bool returnValue = true; if (this->GetState() == Setup) return true; returnValue = m_Device->Disconnect(); this->SetState(Setup); return returnValue; } mitk::PolhemusInterface* mitk::PolhemusTrackingDevice::GetDevice() { return m_Device; } std::vector mitk::PolhemusTrackingDevice::GetAllTools() { return this->m_AllTools; } void mitk::PolhemusTrackingDevice::TrackTools() { try { /* lock the TrackingFinishedMutex to signal that the execution rights are now transfered to the tracking thread */ - MutexLockHolder trackingFinishedLockHolder(*m_TrackingFinishedMutex); // keep lock until end of scope + std::lock_guard trackingFinishedLockHolder(m_TrackingFinishedMutex); // keep lock until end of scope bool localStopTracking; // Because m_StopTracking is used by two threads, access has to be guarded by a mutex. To minimize thread locking, a local copy is used here - this->m_StopTrackingMutex->Lock(); // update the local copy of m_StopTracking + this->m_StopTrackingMutex.lock(); // update the local copy of m_StopTracking localStopTracking = this->m_StopTracking; - this->m_StopTrackingMutex->Unlock(); + this->m_StopTrackingMutex.unlock(); Sleep(100);//Wait a bit until the tracker is ready... while ((this->GetState() == Tracking) && (localStopTracking == false)) { std::vector lastData = this->GetDevice()->GetLastFrame(); if (lastData.size() != m_AllTools.size()) { MITK_WARN << "Tool count is corrupt. Hardware gives " << lastData.size() << " tools, MITK expects " << m_AllTools.size() << " tools. Aborting!"; } else { std::vector allTools = this->GetAllTools(); for (size_t i = 0; i < allTools.size(); i++) { mitk::PolhemusTool::Pointer currentTool = allTools.at(i); const int distortionLevel = lastData.at(i).distortionLevel; if (distortionLevel == 0) { currentTool->SetDataValid(true); } else { currentTool->SetDataValid(false); } currentTool->SetDistortionLevel(distortionLevel); currentTool->SetPosition(lastData.at(i).pos); currentTool->SetOrientation(lastData.at(i).rot); currentTool->SetIGTTimeStamp(mitk::IGTTimeStamp::GetInstance()->GetElapsed()); } } /* Update the local copy of m_StopTracking */ - this->m_StopTrackingMutex->Lock(); + this->m_StopTrackingMutex.lock(); localStopTracking = m_StopTracking; - this->m_StopTrackingMutex->Unlock(); + this->m_StopTrackingMutex.unlock(); } } catch (...) { this->StopTracking(); mitkThrowException(mitk::IGTHardwareException) << "Error while trying to track tools. Thread stopped."; } } -ITK_THREAD_RETURN_TYPE mitk::PolhemusTrackingDevice::ThreadStartTracking(void* pInfoStruct) +void mitk::PolhemusTrackingDevice::ThreadStartTracking() { - /* extract this pointer from Thread Info structure */ - struct itk::MultiThreader::ThreadInfoStruct * pInfo = (struct itk::MultiThreader::ThreadInfoStruct*)pInfoStruct; - if (pInfo == nullptr) - { - return ITK_THREAD_RETURN_VALUE; - } - if (pInfo->UserData == nullptr) - { - return ITK_THREAD_RETURN_VALUE; - } - PolhemusTrackingDevice *trackingDevice = (PolhemusTrackingDevice*)pInfo->UserData; - - if (trackingDevice != nullptr) - trackingDevice->TrackTools(); - - return ITK_THREAD_RETURN_VALUE; + this->TrackTools(); } bool mitk::PolhemusTrackingDevice::AutoDetectToolsAvailable() { return true; } mitk::NavigationToolStorage::Pointer mitk::PolhemusTrackingDevice::AutoDetectTools() { std::vector singeFrameData = this->m_Device->AutoDetectTools(); MITK_INFO << "Found " << singeFrameData.size() << " tools."; mitk::NavigationToolStorage::Pointer returnValue = mitk::NavigationToolStorage::New(); for each (mitk::PolhemusInterface::trackingData t in singeFrameData) { mitk::NavigationTool::Pointer newTool = mitk::NavigationTool::New(); std::stringstream name; name << "Sensor-" << ((int)t.id); newTool->GetDataNode()->SetName(name.str()); //The identifier defines, which plug is used (e.g. "Sens 2" --> 2). std::stringstream identifier; identifier << ((int)t.id); newTool->SetIdentifier(identifier.str()); newTool->SetTrackingDeviceType(mitk::PolhemusTrackerTypeInformation::GetDeviceDataPolhemusTrackerLiberty().Line); returnValue->AddTool(newTool); } return returnValue; } void mitk::PolhemusTrackingDevice::SetHemisphereTrackingEnabled(bool _HemisphereTrackingEnabled) { //We need to remember if HemisphereTracking is switch on for this reason: /* m_Device->SetHemi works only if the device is connected. However, GUI can also change if it is not connected. In this case, we remember it in the m_HemisphereTrackingEnabled variable. And when connecting, we know, which status is wanted from the user by GUI. */ m_HemisphereTrackingEnabled = _HemisphereTrackingEnabled; this->m_Device->SetHemisphereTrackingEnabled(_HemisphereTrackingEnabled); } void mitk::PolhemusTrackingDevice::ToggleHemisphere(int _tool) { this->m_Device->ToggleHemisphere(_tool); } void mitk::PolhemusTrackingDevice::SetHemisphere(int _tool, mitk::Vector3D _hemisphere) { //If you set a hemisphere vector which is unequal (0|0|0), this means, that there is no hemisphere tracking any more //disable the option, so that it can be reactivated... Also if it is just a single tool. if (_hemisphere.GetNorm() != 0) m_HemisphereTrackingEnabled = false; this->m_Device->SetHemisphere(_tool, _hemisphere); } mitk::Vector3D mitk::PolhemusTrackingDevice::GetHemisphere(int _tool) { return this->m_Device->GetHemisphere(_tool); } bool mitk::PolhemusTrackingDevice::GetHemisphereTrackingEnabled(int _tool) { return this->m_Device->GetHemisphereTrackingEnabled(_tool); } void mitk::PolhemusTrackingDevice::AdjustHemisphere(int _tool) { return this->m_Device->AdjustHemisphere(_tool); } diff --git a/Modules/IGT/TrackingDevices/mitkPolhemusTrackingDevice.h b/Modules/IGT/TrackingDevices/mitkPolhemusTrackingDevice.h index 0041bfa508..19261168a9 100644 --- a/Modules/IGT/TrackingDevices/mitkPolhemusTrackingDevice.h +++ b/Modules/IGT/TrackingDevices/mitkPolhemusTrackingDevice.h @@ -1,161 +1,160 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef MITKPolhemusTRACKINGDEVICE_H_HEADER_INCLUDED_ #define MITKPolhemusTRACKINGDEVICE_H_HEADER_INCLUDED_ #include #include #include #include -#include +#include namespace mitk { /** Documentation: * \brief An object of this class represents Polhemus tracking device. You can add tools to this * device, then open the connection and start tracking. The tracking device will then * continuously update the tool coordinates. * The tools which are used by Polhemus need to be connected to the correct port. * The port of the tool is stored as m_ToolPort in PolhemusTool AND as identifier in the NavigationTool (ToolStorage). * \ingroup IGT */ class MITKIGT_EXPORT PolhemusTrackingDevice : public TrackingDevice { public: mitkClassMacro(PolhemusTrackingDevice, TrackingDevice); itkFactorylessNewMacro(Self); itkCloneMacro(Self); /** * \brief Starts the tracking. * \return Returns true if the tracking is started. Throws an exception if an error occures. * @throw mitk::IGTHardwareException Throws an exception if there is an error during start tracking. */ virtual bool StartTracking() override; /** * \brief Stops the tracking. * \return Returns true if the tracking is stopped. */ virtual bool StopTracking() override; /** * \brief Opens the connection to the device. This have to be done before the tracking is started. * @throw mitk::IGTHardwareException Throws an exception if there is an error during open connection. */ virtual bool OpenConnection() override; /** * \brief Closes the connection and clears all resources. */ virtual bool CloseConnection() override; /** * \return Returns the number of tools which have been added to the device. */ virtual unsigned int GetToolCount() const override; /** * \param toolNumber The number of the tool which should be given back. * \return Returns the tool which the number "toolNumber". Returns NULL, if there is * no tool with this number. */ TrackingTool* GetTool(unsigned int toolNumber) const override; /** * \brief Create a new Polhemus tool with toolName and add it to the list of tools * * This method will create a new PolhemusTool object, * set the tool name toolName and then add it to the list of tools. * It returns a pointer of type mitk::TrackingTool to the tool * that can be used to read tracking data from it. * This is the only way to add tools to PolhemusTrackingDevice. * * \warning adding tools is not possible in tracking mode, only in setup and ready. */ mitk::TrackingTool* AddTool(const char* toolName, int toolPort); bool IsDeviceInstalled(); /** @return Returns true if this device can autodetects its tools. */ virtual bool AutoDetectToolsAvailable(); /** Autodetects tools from this device and returns them as a navigation tool storage. * @return Returns the detected tools. Returns an empty storage if no tools are present * or if detection is not possible */ virtual mitk::NavigationToolStorage::Pointer AutoDetectTools(); /** Enables/disables hemisphere tracking for all sensors. */ void SetHemisphereTrackingEnabled(bool _HemisphereTrackingEnabled); /** Is Hemisphere Tracking Enabled for this tool? */ bool GetHemisphereTrackingEnabled(int _tool); /** Toggles the current hemisphere. Parameter _tool describes, for which tool the hemisphere should change. Default -1 toggles all tools.*/ void ToggleHemisphere(int _tool = -1); /** Sets the Hemisphere of tool _tool to the vector _hemisphere */ void SetHemisphere(int _tool, mitk::Vector3D _hemisphere); /** Get the Hemisphere for _tool as mitk vector */ mitk::Vector3D GetHemisphere(int _tool); /** Adjust the Hemisphere for this tool. User needs to make sure, that the tool is located in hemisphere (1|0|0) when calling this function. In contrast to SetHemisphere(1,0,0), this method restores the original HemisphereTracking settings at the end. */ void AdjustHemisphere(int _tool); protected: PolhemusTrackingDevice(); ~PolhemusTrackingDevice(); /** * \brief Adds a tool to the tracking device. * * \param tool The tool which will be added. * \return Returns true if the tool has been added, false otherwise. */ bool InternalAddTool(PolhemusTool::Pointer tool); /** * \brief This method tracks tools as long as the variable m_Mode is set to "Tracking". * Tracking tools means grabbing frames from the camera an updating the tools. * @throw mitk::IGTHardwareException Throws an exception if there is an error during tracking of tools. */ void TrackTools(); /** * \return Returns all tools of the tracking device. */ std::vector GetAllTools(); /** * \return Gives back the device which is represented by an object of the class PolhemusInterface. */ PolhemusInterface* GetDevice(); - static ITK_THREAD_RETURN_TYPE ThreadStartTracking(void* data); + void ThreadStartTracking(); std::vector m_AllTools; ///< vector holding all tools PolhemusInterface::Pointer m_Device; ///< represents the interface to the tracking hardware - itk::MultiThreader::Pointer m_MultiThreader; - int m_ThreadID; + std::thread m_Thread; bool m_HemisphereTrackingEnabled; }; }//mitk #endif /* MITKPolhemusTRACKINGDEVICE_H_HEADER_INCLUDED_ */ diff --git a/Modules/US/USFilters/mitkUSImageSource.cpp b/Modules/US/USFilters/mitkUSImageSource.cpp index 411a8bd76e..7221679399 100644 --- a/Modules/US/USFilters/mitkUSImageSource.cpp +++ b/Modules/US/USFilters/mitkUSImageSource.cpp @@ -1,121 +1,120 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkUSImageSource.h" #include "mitkProperties.h" const char* mitk::USImageSource::IMAGE_PROPERTY_IDENTIFIER = "id_nummer"; mitk::USImageSource::USImageSource() : m_OpenCVToMitkFilter(mitk::OpenCVToMitkImageFilter::New()), m_MitkToOpenCVFilter(nullptr), m_ImageFilter(mitk::BasicCombinationOpenCVImageFilter::New()), m_CurrentImageId(0) { } mitk::USImageSource::~USImageSource() { } void mitk::USImageSource::PushFilter(AbstractOpenCVImageFilter::Pointer filter) { m_ImageFilter->PushFilter(filter); } bool mitk::USImageSource::RemoveFilter(AbstractOpenCVImageFilter::Pointer filter) { return m_ImageFilter->RemoveFilter(filter); } bool mitk::USImageSource::GetIsFilterInThePipeline(AbstractOpenCVImageFilter::Pointer filter) { return m_ImageFilter->GetIsFilterOnTheList(filter); } std::vector mitk::USImageSource::GetNextImage() { std::vector result; // Apply OpenCV based filters beforehand if (m_ImageFilter.IsNotNull() && !m_ImageFilter->GetIsEmpty()) { std::vector imageVector; GetNextRawImage(imageVector); if(result.size() != imageVector.size()) result.resize(imageVector.size()); for (size_t i = 0; i < imageVector.size(); ++i) { if (!imageVector[i].empty()) { m_ImageFilterMutex.lock(); m_ImageFilter->FilterImage(imageVector[i], m_CurrentImageId); m_ImageFilterMutex.unlock(); // convert to MITK image this->m_OpenCVToMitkFilter->SetOpenCVMat(imageVector[i]); this->m_OpenCVToMitkFilter->Update(); // OpenCVToMitkImageFilter returns a standard mitk::image. result[i] = this->m_OpenCVToMitkFilter->GetOutput(); } } } else { this->GetNextRawImage(result); } for (size_t i = 0; i < result.size(); ++i) { if (result[i].IsNotNull()) { result[i]->SetProperty(IMAGE_PROPERTY_IDENTIFIER, mitk::IntProperty::New(m_CurrentImageId)); } else { - //MITK_WARN("mitkUSImageSource") << "Result image " << i << " is not set."; result[i] = mitk::Image::New(); } } m_CurrentImageId++; return result; } void mitk::USImageSource::GetNextRawImage(std::vector& imageVector) { // create filter object if it does not exist yet if (!m_MitkToOpenCVFilter) { m_MitkToOpenCVFilter = mitk::ImageToOpenCVImageFilter::New(); } // get mitk image through virtual method of the subclass std::vector mitkImg; this->GetNextRawImage(mitkImg); for (unsigned int i = 0; i < mitkImg.size(); ++i) { if (mitkImg[i].IsNull() || !mitkImg[i]->IsInitialized()) { imageVector[i] = cv::Mat(); } else { // convert mitk::Image to an OpenCV image m_MitkToOpenCVFilter->SetImage(mitkImg[i]); imageVector[i] = m_MitkToOpenCVFilter->GetOpenCVMat(); } } } diff --git a/Modules/US/USHardwareTelemed/CMakeLists.txt b/Modules/US/USHardwareTelemed/CMakeLists.txt index d97e99aaab..c728db930e 100644 --- a/Modules/US/USHardwareTelemed/CMakeLists.txt +++ b/Modules/US/USHardwareTelemed/CMakeLists.txt @@ -1,22 +1,18 @@ IF(WIN32) OPTION(MITK_USE_US_TELEMED_SDK "Enable support for Telemed api devices" OFF) IF(MITK_USE_US_TELEMED_SDK) -IF(CMAKE_CL_64) - message( FATAL_ERROR "The Telemed API cannot be used in 64 bit builds. Please configure a 32 bit build instead or deactivate MITK_USE_US_TELEMED_SDK." ) -ENDIF(CMAKE_CL_64) - SET(MITK_US_TELEMED_SDK_PATH "" CACHE PATH "Path to Telemed SDK header files.") MITK_CREATE_MODULE( DEPENDS MitkUS INCLUDE_DIRS "${MITK_US_TELEMED_SDK_PATH}" INTERNAL_INCLUDE_DIRS ${INCLUDE_DIRS_INTERNAL} AUTOLOAD_WITH MitkUS ) ENDIF(MITK_USE_US_TELEMED_SDK) ENDIF(WIN32) diff --git a/Modules/US/USHardwareTelemed/mitkUSTelemedDevice.cpp b/Modules/US/USHardwareTelemed/mitkUSTelemedDevice.cpp index 7fd2d11dad..fa2a0ce272 100644 --- a/Modules/US/USHardwareTelemed/mitkUSTelemedDevice.cpp +++ b/Modules/US/USHardwareTelemed/mitkUSTelemedDevice.cpp @@ -1,340 +1,362 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkUSTelemedDevice.h" - +#include "mitkImageReadAccessor.h" #include "mitkUSTelemedSDKHeader.h" mitk::USTelemedDevice::USTelemedDevice(std::string manufacturer, std::string model) : mitk::USDevice(manufacturer, model), m_ControlsProbes(mitk::USTelemedProbesControls::New(this)), m_ControlsBMode(mitk::USTelemedBModeControls::New(this)), m_ControlsDoppler(mitk::USTelemedDopplerControls::New(this)), m_ImageSource(mitk::USTelemedImageSource::New()), m_UsgMainInterface(0), m_Probe(0), m_UsgDataView(0), m_ProbesCollection(0) { - SetNumberOfOutputs(1); + SetNumberOfIndexedOutputs(1); SetNthOutput(0, this->MakeOutput(0)); } mitk::USTelemedDevice::~USTelemedDevice() { } std::string mitk::USTelemedDevice::GetDeviceClass() { return "org.mitk.modules.us.USTelemedDevice"; } mitk::USControlInterfaceBMode::Pointer mitk::USTelemedDevice::GetControlInterfaceBMode() { return m_ControlsBMode.GetPointer(); } mitk::USControlInterfaceProbes::Pointer mitk::USTelemedDevice::GetControlInterfaceProbes() { return m_ControlsProbes.GetPointer(); }; mitk::USControlInterfaceDoppler::Pointer mitk::USTelemedDevice::GetControlInterfaceDoppler() { return m_ControlsDoppler.GetPointer(); }; bool mitk::USTelemedDevice::OnInitialization() { CoInitialize(nullptr); // initialize COM library return true; } bool mitk::USTelemedDevice::OnConnection() { // create main Telemed API COM library object HRESULT hr; hr = CoCreateInstance(Usgfw2Lib::CLSID_Usgfw2, nullptr, CLSCTX_INPROC_SERVER, Usgfw2Lib::IID_IUsgfw2,(LPVOID*) &m_UsgMainInterface); if (FAILED(hr)) { SAFE_RELEASE(m_UsgMainInterface); MITK_ERROR("USDevice")("USTelemedDevice") << "Error at connecting to ultrasound device (" << hr << ")."; return false; } this->ConnectDeviceChangeSink(); return true; } bool mitk::USTelemedDevice::OnDisconnection() { // control objects cannot be active anymore m_ControlsBMode->SetIsActive(false); m_ControlsDoppler->SetIsActive(false); m_ControlsProbes->SetIsActive(false); ReleaseUsgControls(); return true; } bool mitk::USTelemedDevice::OnActivation() { // probe controls are available now m_ControlsProbes->SetIsActive(true); if ( m_ControlsProbes->GetProbesCount() < 1 ) { MITK_WARN("USDevice")("USTelemedDevice") << "No probe found."; return false; } // select first probe as a default m_ControlsProbes->SelectProbe(0); // set scan mode b as default for activation - // control interfaces can override this later HRESULT hr = m_UsgDataView->put_ScanMode(Usgfw2Lib::SCAN_MODE_B); if (FAILED(hr)) { MITK_ERROR("USDevice")("USTelemedDevice") << "Could not set scan mode b (" << hr << ")."; return false; } // start ultrasound scanning with selected scan mode hr = m_UsgDataView->put_ScanState(Usgfw2Lib::SCAN_STATE_RUN); if (FAILED(hr)) { MITK_ERROR("USDevice")("USTelemedDevice") << "Start scanning failed (" << hr << ")."; return false; } m_ControlsBMode->ReinitializeControls(); return true; } bool mitk::USTelemedDevice::OnDeactivation() { this->StopScanning(); return true; } void mitk::USTelemedDevice::OnFreeze(bool freeze) { if ( freeze ) { m_UsgDataView->put_ScanState(Usgfw2Lib::SCAN_STATE_FREEZE); } else { m_UsgDataView->put_ScanState(Usgfw2Lib::SCAN_STATE_RUN); } } +void mitk::USTelemedDevice::GenerateData() +{ + mitk::USTelemedImageSource::Pointer s = dynamic_cast(GetUSImageSource().GetPointer()); + s->GetNextRawImage(m_ImageVector); + Superclass::GenerateData(); +} + mitk::USImageSource::Pointer mitk::USTelemedDevice::GetUSImageSource() { return m_ImageSource.GetPointer(); } void mitk::USTelemedDevice::ReleaseUsgControls() { if (m_UsgDataView) { this->StopScanning(); }; SAFE_RELEASE(m_UsgMainInterface); SAFE_RELEASE(m_Probe); SAFE_RELEASE(m_UsgDataView); SAFE_RELEASE(m_ProbesCollection); } void mitk::USTelemedDevice::StopScanning() { if ( ! m_UsgDataView ) { MITK_WARN("USDevice")("USTelemedDevice") << "Cannot stop scanning as Telemed Data View is null."; return; } HRESULT hr; hr = m_UsgDataView->put_ScanState(Usgfw2Lib::SCAN_STATE_STOP); if (FAILED(hr)) { MITK_ERROR("USDevice")("USTelemedDevice") << "Stop scanning failed (" << hr << ")."; mitkThrow() << "Stop scanning failed (" << hr << ")."; } } +std::vector mitk::USTelemedDevice::GetAllProbes(){ + return m_ControlsProbes->GetProbeSet(); +} + +mitk::USProbe::Pointer mitk::USTelemedDevice::GetCurrentProbe(){ + return m_ControlsProbes->GetSelectedProbe(); +} + +mitk::USProbe::Pointer mitk::USTelemedDevice::GetProbeByName(std::string name){ + for (mitk::USProbe::Pointer p : m_ControlsProbes->GetProbeSet()){ + if (p->GetName().compare(name)==0) {return p;} + } + return nullptr; +} + Usgfw2Lib::IUsgfw2* mitk::USTelemedDevice::GetUsgMainInterface() { return m_UsgMainInterface; } void mitk::USTelemedDevice::SetActiveDataView(Usgfw2Lib::IUsgDataView* usgDataView) { // do nothing if the usg data view hasn't changed if ( m_UsgDataView != usgDataView ) { // scan converter plugin is connected to IUsgDataView -> a new plugin // must be created when changing IUsgDataView m_UsgDataView = usgDataView; if ( ! m_ImageSource->CreateAndConnectConverterPlugin(m_UsgDataView, Usgfw2Lib::SCAN_MODE_B)) { return; } // b mode control object must know about active data view m_ControlsBMode->SetUsgDataView(m_UsgDataView); } } void mitk::USTelemedDevice::ConnectDeviceChangeSink( ) { IConnectionPointContainer* cpc = nullptr; HRESULT hr = m_UsgMainInterface->QueryInterface(IID_IConnectionPointContainer, (void**)&cpc); if (hr != S_OK) cpc = nullptr; if (cpc != nullptr) hr = cpc->FindConnectionPoint(Usgfw2Lib::IID_IUsgDeviceChangeSink, &m_UsgDeviceChangeCpnt); if (hr != S_OK) { m_UsgDeviceChangeCpnt = nullptr; m_UsgDeviceChangeCpntCookie = 0; } SAFE_RELEASE(cpc); if (m_UsgDeviceChangeCpnt != nullptr) hr = m_UsgDeviceChangeCpnt->Advise((IUnknown*)((Usgfw2Lib::IUsgDeviceChangeSink*)this), &m_UsgDeviceChangeCpntCookie); } // --- Methods for Telemed API Interfaces HRESULT __stdcall mitk::USTelemedDevice::raw_OnBeamformerArrive(IUnknown *pUsgBeamformer, ULONG *reserved) { this->Connect(); return S_OK; } HRESULT __stdcall mitk::USTelemedDevice::raw_OnBeamformerRemove(IUnknown *pUsgBeamformer, ULONG *reserved) { if ( this->GetIsActive() ) { this->Deactivate(); } this->Disconnect(); return S_OK; } HRESULT __stdcall mitk::USTelemedDevice::raw_OnProbeArrive(IUnknown*, ULONG* probeIndex) { m_ControlsProbes->ProbeAdded(static_cast(*probeIndex)); this->Activate(); return S_OK; }; HRESULT __stdcall mitk::USTelemedDevice::raw_OnProbeRemove(IUnknown*, ULONG* probeIndex) { m_ControlsProbes->ProbeRemoved(static_cast(*probeIndex)); if ( this->GetIsActive() ) { this->Deactivate(); } return S_OK; }; STDMETHODIMP_(ULONG) mitk::USTelemedDevice::AddRef() { ++m_RefCount; return m_RefCount; } STDMETHODIMP_(ULONG) mitk::USTelemedDevice::Release() { --m_RefCount; return m_RefCount; } STDMETHODIMP mitk::USTelemedDevice::QueryInterface(REFIID riid, void** ppv) { if (riid == IID_IUnknown || riid == Usgfw2Lib::IID_IUsgDeviceChangeSink) { *ppv = (IUsgDeviceChangeSink*)this; return S_OK; } if (riid == IID_IDispatch) { *ppv = (IDispatch*)this; return S_OK; } return E_NOINTERFACE; } HRESULT mitk::USTelemedDevice::GetTypeInfoCount(UINT *pctinfo) { if (pctinfo == nullptr) return E_INVALIDARG; *pctinfo = 0; return S_OK; } HRESULT mitk::USTelemedDevice::GetTypeInfo(UINT itinfo, LCID lcid, ITypeInfo** pptinfo) { if (pptinfo == nullptr) return E_INVALIDARG; *pptinfo = nullptr; if(itinfo != 0) return DISP_E_BADINDEX; return S_OK; } HRESULT mitk::USTelemedDevice::GetIDsOfNames(const IID &riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgdispid) { // this is not used - must use the same fixed dispid's from Usgfw2 idl file return S_OK; } HRESULT mitk::USTelemedDevice::Invoke(DISPID dispIdMember, const IID &riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) { if ( (dispIdMember >= 1) && (dispIdMember <= 6) ) { if (pDispParams->cArgs != 2) // we need 2 arguments return S_OK; IUnknown *unkn = nullptr; ULONG *res = nullptr; VARIANTARG* p1; VARIANTARG* p; p1 = pDispParams->rgvarg; p = p1; if (p->vt == (VT_BYREF|VT_UI4)) res = p->pulVal; p1++; p = p1; if (p->vt == VT_UNKNOWN) unkn = (IUnknown*)(p->punkVal); if (dispIdMember == 1) OnProbeArrive(unkn, res); else if (dispIdMember == 2) OnBeamformerArrive(unkn, res); else if (dispIdMember == 3) OnProbeRemove(unkn, res); else if (dispIdMember == 4) OnBeamformerRemove(unkn, res); else if (dispIdMember == 5) OnProbeStateChanged(unkn, res); else if (dispIdMember == 6) OnBeamformerStateChanged(unkn, res); } return S_OK; } diff --git a/Modules/US/USHardwareTelemed/mitkUSTelemedDevice.h b/Modules/US/USHardwareTelemed/mitkUSTelemedDevice.h index 36ffefa0ac..f5d9f03e45 100644 --- a/Modules/US/USHardwareTelemed/mitkUSTelemedDevice.h +++ b/Modules/US/USHardwareTelemed/mitkUSTelemedDevice.h @@ -1,181 +1,207 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef MITKUSTelemedDevice_H_HEADER_INCLUDED_ #define MITKUSTelemedDevice_H_HEADER_INCLUDED_ #include "mitkUSDevice.h" #include "mitkUSTelemedImageSource.h" #include "mitkUSTelemedScanConverterPlugin.h" #include "mitkUSTelemedProbesControls.h" #include "mitkUSTelemedBModeControls.h" #include "mitkUSTelemedDopplerControls.h" #include "mitkUSTelemedSDKHeader.h" namespace mitk { /** * \brief Implementation of mitk::USDevice for Telemed API devices. * Connects to a Telemed API device through its COM library interface. * * This class handles all API communications and creates interfaces for * b mode, doppler and probes controls. * Images given by the device are put into an object of * mitk::USTelemedImageSource. * * It implements IUsgDeviceChangeSink of the Telemed API to be notified * of changes to beamformer device or probes (e.g. probe change). */ class USTelemedDevice : public USDevice, public Usgfw2Lib::IUsgDeviceChangeSink { public: mitkClassMacro(USTelemedDevice, mitk::USDevice); mitkNewMacro2Param(Self, std::string, std::string); /** * \brief Returns the class of the device. */ virtual std::string GetDeviceClass(); virtual USControlInterfaceBMode::Pointer GetControlInterfaceBMode(); virtual USControlInterfaceProbes::Pointer GetControlInterfaceProbes(); virtual USControlInterfaceDoppler::Pointer GetControlInterfaceDoppler(); /** * \brief Is called during the initialization process. * There is nothing done on the initialization of a mik::USTelemedDevive object. * * \return always true */ virtual bool OnInitialization(); /** * \brief Is called during the connection process. * Connect to the Telemed API and try to get available probes from the device. * * \return true if successfull, false if no device is connected to the pc * \throws mitk::Exception if something goes wrong at the API calls */ virtual bool OnConnection(); /** * \brief Is called during the disconnection process. * Deactivate and remove all Telemed API controls. A disconnect from the * Telemed API is not possible for which reason the hardware stays in connected * state even after calling this method. * * \return always true * \throws mitk::Exception if something goes wrong at the API calls */ virtual bool OnDisconnection(); /** * \brief Is called during the activation process. * After this method is finished, the device is generating images in b mode. * Changing scanning mode is possible afterwards by using the appropriate * control interfaces. * * \return always true * \throws mitk::Exception if something goes wrong at the API calls */ virtual bool OnActivation(); /** * \brief Is called during the deactivation process. * After a call to this method the device is connected, but not producing images anymore. * * \return always true * \throws mitk::Exception if something goes wrong at the API calls */ virtual bool OnDeactivation(); /** * \brief Changes scan state of the device if freeze is toggeled in mitk::USDevice. */ virtual void OnFreeze(bool freeze); /** @return Returns the current image source of this device. */ USImageSource::Pointer GetUSImageSource( ); + /** + * \brief Returns all probes for this device or an empty vector it no probes were set + * Returns a std::vector of all probes that exist for this device if there were probes set while creating or modifying this USVideoDevice. + * Otherwise it returns an empty vector. Therefore always check if vector is filled, before using it! + */ + std::vector GetAllProbes(); + + /** + * \brief Return current active probe for this USDevice + * Returns a pointer to the probe that is currently in use. If there were probes set while creating or modifying this USDevice. + * Returns null otherwise + */ + mitk::USProbe::Pointer GetCurrentProbe(); + + /** + * \brief get the probe by its name + * Returns a pointer to the probe identified by the given name. If no probe of given name exists for this Device 0 is returned. + */ + mitk::USProbe::Pointer GetProbeByName(std::string name); + + /** + * \brief Grabs the next frame from the Video input. + * This method is called internally, whenever Update() is invoked by an Output. + */ + void GenerateData() override; + /** * \brief Getter for main Telemed API object. * This method is for being called by Telemed control interfaces. */ Usgfw2Lib::IUsgfw2* GetUsgMainInterface(); /** * \brief Changes active IUsgDataView of the device. * This method is for being called by Telemed control interfaces. */ void SetActiveDataView(Usgfw2Lib::IUsgDataView*); // Methods implemented for IUsgDeviceChangeSink virtual HRESULT __stdcall raw_OnProbeArrive(IUnknown *pUsgProbe, ULONG *reserved); virtual HRESULT __stdcall raw_OnBeamformerArrive(IUnknown *pUsgBeamformer, ULONG *reserved); virtual HRESULT __stdcall raw_OnProbeRemove(IUnknown *pUsgProbe, ULONG *reserved); virtual HRESULT __stdcall raw_OnBeamformerRemove(IUnknown *pUsgBeamformer, ULONG *reserved); virtual HRESULT __stdcall raw_OnProbeStateChanged(IUnknown *pUsgProbe, ULONG *reserved) { return S_OK; }; virtual HRESULT __stdcall raw_OnBeamformerStateChanged(IUnknown *pUsgBeamformer, ULONG *reserved) { return S_OK; }; // Methods implemented for IUnknown (necessary for IUsgDeviceChangeSink) STDMETHODIMP_(ULONG) AddRef(); STDMETHODIMP_(ULONG) Release(); STDMETHODIMP QueryInterface(REFIID riid, void** ppv); // Methods implemented for IDispatch (necessary for IUsgDeviceChangeSink) virtual HRESULT STDMETHODCALLTYPE GetTypeInfoCount(UINT *pctinfo); virtual HRESULT STDMETHODCALLTYPE GetTypeInfo(UINT itinfo, LCID lcid, ITypeInfo** pptinfo); virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames(const IID &riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgdispid); virtual HRESULT STDMETHODCALLTYPE Invoke(DISPID dispIdMember, const IID &riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr); protected: /** * Constructs a mitk::USTelemedDevice object by given manufacturer * and model string. These strings are just for labeling the device * in the micro service. * * Control interfaces and image source are available directly after * construction. Registration at the micro service happens not before * initialization method was called. */ USTelemedDevice(std::string manufacturer, std::string model); virtual ~USTelemedDevice(); void ReleaseUsgControls( ); void ConnectDeviceChangeSink( ); /** * \brief Stop ultrasound scanning by Telemed API call. * * \throw mitk::Exception if API call returned with an error */ void StopScanning( ); USTelemedProbesControls::Pointer m_ControlsProbes; USTelemedBModeControls::Pointer m_ControlsBMode; USTelemedDopplerControls::Pointer m_ControlsDoppler; USTelemedImageSource::Pointer m_ImageSource; Usgfw2Lib::IUsgfw2* m_UsgMainInterface; Usgfw2Lib::IProbe* m_Probe; Usgfw2Lib::IUsgDataView* m_UsgDataView; Usgfw2Lib::IUsgCollection* m_ProbesCollection; ULONG m_RefCount; IConnectionPoint* m_UsgDeviceChangeCpnt; DWORD m_UsgDeviceChangeCpntCookie; }; } // namespace mitk #endif // MITKUSTelemedDevice_H_HEADER_INCLUDED_ diff --git a/Modules/US/USHardwareTelemed/mitkUSTelemedImageSource.cpp b/Modules/US/USHardwareTelemed/mitkUSTelemedImageSource.cpp index 1e2d974945..c13bb8a2dd 100644 --- a/Modules/US/USHardwareTelemed/mitkUSTelemedImageSource.cpp +++ b/Modules/US/USHardwareTelemed/mitkUSTelemedImageSource.cpp @@ -1,141 +1,139 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkUSTelemedImageSource.h" #include "mitkUSTelemedSDKHeader.h" #include "MITKUSTelemedScanConverterPlugin.h" #include "mitkImageReadAccessor.h" mitk::USTelemedImageSource::USTelemedImageSource() : m_Image(mitk::Image::New()), - m_ImageMutex(itk::FastMutexLock::New()), + m_ImageMutex(new std::mutex()), m_Plugin(0), m_PluginCallback(0), m_UsgDataView(0), m_ImageProperties(0), m_DepthProperties(0), m_OldnXPelsPerUnit(0), m_OldnYPelsPerUnit(0) { } mitk::USTelemedImageSource::~USTelemedImageSource( ) { SAFE_RELEASE(m_PluginCallback); SAFE_RELEASE(m_Plugin); SAFE_RELEASE(m_ImageProperties); SAFE_RELEASE(m_DepthProperties); + delete m_ImageMutex; } void mitk::USTelemedImageSource::GetNextRawImage(std::vector& imageVector) { if (imageVector.empty() ) { imageVector.push_back( mitk::Image::New()); } //get the actual resolution to check if it changed. We have to do this every time because the geometry takes a few frames to adapt Usgfw2Lib::tagImageResolution resolutionInMetersActual; m_ImageProperties->GetResolution(&resolutionInMetersActual, 0); if (m_OldnXPelsPerUnit != resolutionInMetersActual.nXPelsPerUnit || m_OldnYPelsPerUnit != resolutionInMetersActual.nYPelsPerUnit) { //we can only update if the image exists and has a geometry if (m_Image.IsNotNull() && m_Image->GetGeometry() != nullptr) { m_OldnXPelsPerUnit = resolutionInMetersActual.nXPelsPerUnit; m_OldnYPelsPerUnit = resolutionInMetersActual.nYPelsPerUnit; UpdateImageGeometry(); } } //now update image if ( m_Image->IsInitialized() ) { - m_ImageMutex->Lock(); + m_ImageMutex->lock(); // copy contents of the given image into the member variable imageVector.at(0)->Initialize(m_Image->GetPixelType(), m_Image->GetDimension(), m_Image->GetDimensions()); mitk::ImageReadAccessor inputReadAccessor(m_Image, m_Image->GetSliceData(0,0,0)); imageVector.at(0)->SetSlice(inputReadAccessor.GetData()); imageVector.at(0)->SetGeometry(m_Image->GetGeometry()); - - m_ImageMutex->Unlock(); + m_ImageMutex->unlock(); } - } void mitk::USTelemedImageSource::UpdateImageGeometry() { Usgfw2Lib::tagPixelsOrigin origin = Usgfw2Lib::tagPixelsOrigin(); Usgfw2Lib::tagImageResolution resolutionInMeters; m_ImageProperties->GetResolution(&resolutionInMeters,0); mitk::Vector3D spacing; spacing[0] = ((double)1 / resolutionInMeters.nXPelsPerUnit) * 1000; //conversion: meters to millimeters spacing[1] = ((double)1 / resolutionInMeters.nXPelsPerUnit) * 1000; //conversion: meters to millimeters spacing[2] = 1; - m_ImageMutex->Lock(); + m_ImageMutex->lock(); if(m_Image.IsNotNull() && (m_Image->GetGeometry()!=nullptr)) { m_Image->GetGeometry()->SetSpacing(spacing); m_Image->GetGeometry()->Modified(); } else {MITK_WARN << "image or geometry was nullptr, can't adapt geometry";} - m_ImageMutex->Unlock(); + m_ImageMutex->unlock(); MITK_DEBUG << "UpdateImageGeometry called!"; MITK_DEBUG << "depth: " << m_DepthProperties->GetCurrent(); MITK_DEBUG << "new spacing: " << spacing; } bool mitk::USTelemedImageSource::CreateAndConnectConverterPlugin(Usgfw2Lib::IUsgDataView* usgDataView, Usgfw2Lib::tagScanMode scanMode) { IUnknown* tmp_obj = nullptr; - // create control object from Telemed API mitk::telemed::CreateUsgControl( usgDataView, Usgfw2Lib::IID_IUsgScanConverterPlugin, scanMode, 0, (void**)&tmp_obj ); if ( ! tmp_obj ) { MITK_ERROR("USImageSource")("USTelemedImageSource") << "Could not create scan converter plugin."; return false; } // create the callback object for the scan conversion if ( ! m_PluginCallback ) { m_PluginCallback = new USTelemedScanConverterPlugin(); // current image buffer should be copied to m_Image at every callback m_PluginCallback->SetOutputImage(m_Image.GetPointer(), m_ImageMutex); } else { // make sure that the scan converter plugin is not set // to the plugin callback any longer m_PluginCallback->SetScanConverterPlugin(0); } // now the ScanConverterPlugin can be created and set as plugin SAFE_RELEASE(m_Plugin); m_Plugin = (Usgfw2Lib::IUsgScanConverterPlugin*)tmp_obj; m_PluginCallback->SetScanConverterPlugin(m_Plugin); //last: create some connections which are needed inside this class for communication with the telemed device m_UsgDataView = usgDataView; // create telemed controls if (!m_DepthProperties) {CREATE_TelemedControl(m_DepthProperties, m_UsgDataView, Usgfw2Lib::IID_IUsgDepth, Usgfw2Lib::IUsgDepth, Usgfw2Lib::SCAN_MODE_B);} if (!m_ImageProperties) {CREATE_TelemedControl(m_ImageProperties, m_UsgDataView, Usgfw2Lib::IID_IUsgImageProperties, Usgfw2Lib::IUsgImageProperties, Usgfw2Lib::SCAN_MODE_B);} return true; } diff --git a/Modules/US/USHardwareTelemed/mitkUSTelemedImageSource.h b/Modules/US/USHardwareTelemed/mitkUSTelemedImageSource.h index c66ad171d5..b8f5f4bd4c 100644 --- a/Modules/US/USHardwareTelemed/mitkUSTelemedImageSource.h +++ b/Modules/US/USHardwareTelemed/mitkUSTelemedImageSource.h @@ -1,79 +1,77 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef MITKUSTelemedImageSource_H_HEADER_INCLUDED_ #define MITKUSTelemedImageSource_H_HEADER_INCLUDED_ #include "mitkUSImageSource.h" #include "mitkUSTelemedSDKHeader.h" #include "mitkUSTelemedScanConverterPlugin.h" -#include "itkFastMutexLock.h" - namespace mitk { /** * \brief Implementation of mitk::USImageSource for Telemed API devices. * The method mitk::USImageSource::GetNextRawImage() is implemented for * getting images from the Telemed API. * * A method for connecting this ImageSource to the Telemed API is * implemented (mitk::USTelemedImageSource::CreateAndConnectConverterPlugin()). * This method is available for being used by mitk::USTelemedDevice. */ class USTelemedImageSource : public USImageSource { public: mitkClassMacro(USTelemedImageSource, USImageSource); itkFactorylessNewMacro(Self); itkCloneMacro(Self); /** * Implementation of the superclass method. Returns the pointer * to the mitk::Image filled by Telemed API callback. */ virtual void GetNextRawImage( std::vector& ); /** * Updates the geometry of the current image from the API. * Is used internally when a new image is initialized, but * also needs to be called if, e.g., the zoom factor is changed. */ void UpdateImageGeometry(); /** * \brief Connect this object to the Telemed API. * This method is for being used by mitk::USTelemedDevice. */ bool CreateAndConnectConverterPlugin( Usgfw2Lib::IUsgDataView*, Usgfw2Lib::tagScanMode ); protected: USTelemedImageSource( ); virtual ~USTelemedImageSource( ); Usgfw2Lib::IUsgScanConverterPlugin* m_Plugin; USTelemedScanConverterPlugin* m_PluginCallback; Usgfw2Lib::IUsgDataView* m_UsgDataView; // main SDK object for comminucating with the Telemed API //API objects for communication, used to get the right geometry Usgfw2Lib::IUsgImageProperties* m_ImageProperties; Usgfw2Lib::IUsgDepth* m_DepthProperties; long m_OldnXPelsPerUnit; long m_OldnYPelsPerUnit; - mitk::Image::Pointer m_Image; - itk::FastMutexLock::Pointer m_ImageMutex; + mitk::Image::Pointer m_Image; + std::mutex* m_ImageMutex; }; } // namespace mitk #endif // MITKUSTelemedImageSource_H diff --git a/Modules/US/USHardwareTelemed/mitkUSTelemedProbesControls.cpp b/Modules/US/USHardwareTelemed/mitkUSTelemedProbesControls.cpp index 36c643c832..a795c380f0 100644 --- a/Modules/US/USHardwareTelemed/mitkUSTelemedProbesControls.cpp +++ b/Modules/US/USHardwareTelemed/mitkUSTelemedProbesControls.cpp @@ -1,243 +1,243 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkUSTelemedProbesControls.h" #include "mitkUSTelemedDevice.h" #include mitk::USTelemedProbesControls::USTelemedProbesControls(itk::SmartPointer device) : mitk::USControlInterfaceProbes(device.GetPointer()), m_IsActive(false), m_TelemedDevice(device), m_ProbesCollection(0), m_Probe(0) { } mitk::USTelemedProbesControls::~USTelemedProbesControls() { SAFE_RELEASE(m_ProbesCollection); } void mitk::USTelemedProbesControls::SetIsActive(bool isActive) { if ( ! m_TelemedDevice ) { MITK_WARN("USTelemedProbesControls")("USControlInterfaceProbes") << "Cannot activate probe controls while device is not set."; return; } if ( isActive && m_ProbesCollection == 0 ) { this->CreateProbesCollection(); this->CreateProbesSet(); } else { } m_IsActive = isActive; } bool mitk::USTelemedProbesControls::GetIsActive() { return m_IsActive; } std::vector mitk::USTelemedProbesControls::GetProbeSet() { // create a new vector of base class (USProbe) objects, because // interface wants a vector of this type - std::vector usProbes(m_ProbesSet.size(), 0); + std::vector usProbes; for (unsigned int n = 0; n < m_ProbesSet.size(); ++n) { - usProbes.at(n) = m_ProbesSet.at(n).GetPointer(); + usProbes.push_back(m_ProbesSet.at(n).GetPointer()); } return usProbes; } void mitk::USTelemedProbesControls::OnSelectProbe(unsigned int index) { if (index >= m_ProbesSet.size()) { MITK_ERROR("USTelemedProbesControls")("USControlInterfaceProbes") << "Cannot select probe with index " << index << ". Maximum possible index is " << m_ProbesSet.size()-1 << "."; mitkThrow() << "Cannot select probe with index " << index << ". Maximum possible index is " << m_ProbesSet.size()-1 << "."; } m_TelemedDevice->SetActiveDataView(m_ProbesSet.at(index)->GetUsgDataView()); m_SelectedProbeIndex = index; } void mitk::USTelemedProbesControls::OnSelectProbe(mitk::USProbe::Pointer probe) { } mitk::USProbe::Pointer mitk::USTelemedProbesControls::GetSelectedProbe() { if (m_SelectedProbeIndex >= m_ProbesSet.size()) { MITK_ERROR("USTelemedProbesControls")("USControlInterfaceProbes") << "Cannot get active probe as the current index is" << m_SelectedProbeIndex << ". Maximum possible index is " << m_ProbesSet.size()-1 << "."; mitkThrow() << "Cannot get active probe as the current index is" << m_SelectedProbeIndex << ". Maximum possible index is " << m_ProbesSet.size()-1 << "."; } return m_ProbesSet.at(m_SelectedProbeIndex).GetPointer(); } unsigned int mitk::USTelemedProbesControls::GetProbesCount() const { return m_ProbesSet.size(); } /*void mitk::USTelemedProbesControls::SetTelemedDevice(itk::SmartPointer telemedDevice) { m_TelemedDevice = telemedDevice; }*/ void mitk::USTelemedProbesControls::ProbeRemoved(unsigned int index) { MITK_INFO << "Probe removed..."; if ( m_ProbesSet.size() > index ) { m_ProbesSet.erase(m_ProbesSet.begin() + index); } } void mitk::USTelemedProbesControls::ProbeAdded(unsigned int index) { MITK_INFO << "Probe arrived..."; this->CreateProbesCollection(); this->CreateProbesSet(); // Activate the added probe, if the added probe is the first probe if (m_ProbesSet.size() == 1) { m_TelemedDevice->SetActiveDataView(m_ProbesSet.at(0)->GetUsgDataView()); } } bool mitk::USTelemedProbesControls::CreateProbesCollection() { IUnknown* tmp_obj = nullptr; HRESULT hr; // get the main API interface from the Telemed device Usgfw2Lib::IUsgfw2* usgMainInterface = m_TelemedDevice->GetUsgMainInterface(); if ( ! usgMainInterface ) { MITK_ERROR("USTelemedProbesControls")("USControlInterfaceProbes") << "Main interface of Telemed device must not be null."; mitkThrow() << "Main interface of Telemed device must not be null."; } // get probes collection from Telemed API hr = usgMainInterface->get_ProbesCollection(&tmp_obj); if (FAILED(hr) || ! tmp_obj) { MITK_WARN("USTelemedProbesControls")("USControlInterfaceProbes") << "Error on getting probes collection (" << hr << ")."; return false; } // second step for getting probes collection from Telemed API SAFE_RELEASE(m_ProbesCollection); hr = tmp_obj->QueryInterface(Usgfw2Lib::IID_IUsgCollection,(void**)&m_ProbesCollection); SAFE_RELEASE(tmp_obj); if (FAILED(hr) || ! m_ProbesCollection) { MITK_WARN("USTelemedProbesControls")("USControlInterfaceProbes") << "Error on querying interface for probes collection (" << hr << ")."; return false; } return true; } void mitk::USTelemedProbesControls::CreateProbesSet() { if ( ! m_ProbesCollection) { MITK_ERROR("USTelemedProbesControls")("USControlInterfaceProbes") << "Cannot get probe set without ProbesCollection being initialized before."; mitkThrow() << "Cannot get probe set without ProbesCollection being initialized before."; } // get number of available probes LONG probes_count = 0; HRESULT hr = m_ProbesCollection->get_Count(&probes_count); if (FAILED(hr)) { mitkThrow() << "Could not get probes count (" << hr << ")."; } if ( ! m_TelemedDevice ) { MITK_ERROR("USTelemedProbesControls")("USControlInterfaceProbes") << "Telemed device must not be null when creating probes set."; mitkThrow() << "Telemed device must not be null when creating probes set."; } // get the main API interface from the Telemed device Usgfw2Lib::IUsgfw2* usgMainInterface = m_TelemedDevice->GetUsgMainInterface(); if ( ! usgMainInterface ) { MITK_ERROR("USTelemedProbesControls")("USControlInterfaceProbes") << "Usg main interface must not be null when creating probes set."; mitkThrow() << "Usg main interface must not be null when creating probes set."; } // initialize probes set with new vector - m_ProbesSet = std::vector(probes_count, 0); + m_ProbesSet = std::vector(); for (LONG n = 0; n < probes_count; ++n) { // get the probe item from the API collection IUnknown* tmp_obj = nullptr; hr = m_ProbesCollection->Item(n,&tmp_obj); if (FAILED(hr)) { MITK_ERROR("USTelemedProbesControls")("USControlInterfaceProbes") << "Could not get probe with index " << n << "."; mitkThrow() << "Could not get probe with index " << n << "."; } // convert this item to a probe Usgfw2Lib::IProbe* probe; hr = tmp_obj->QueryInterface(Usgfw2Lib::IID_IProbe,(void**)&probe); if (FAILED(hr)) { MITK_ERROR("USTelemedProbesControls")("USControlInterfaceProbes") << "Error on querying interface for probe with index "<< n << "."; mitkThrow() << "Error on querying interface for probe with index "<< n << "."; } // create main ultrasound scanning object for selected probe Usgfw2Lib::IUsgDataView* usgDataView; Usgfw2Lib::IUsgDataViewPtr usgDataViewTmp; usgDataViewTmp = usgMainInterface->CreateDataView(probe); usgDataViewTmp->QueryInterface(Usgfw2Lib::IID_IUsgDataView, (void**)&usgDataView); if (! usgDataView) { MITK_ERROR("USTelemedProbesControls")("USControlInterfaceProbes") << "Could not create data view for selected probe."; mitkThrow() << "Could not create data view for selected probe."; } // probe object can be created now from API data - m_ProbesSet.at(n) = mitk::USTelemedProbe::New(probe, usgDataView); + m_ProbesSet.push_back(mitk::USTelemedProbe::New(probe, usgDataView)); SAFE_RELEASE(tmp_obj); } } diff --git a/Modules/US/USHardwareTelemed/mitkUSTelemedScanConverterPlugin.cpp b/Modules/US/USHardwareTelemed/mitkUSTelemedScanConverterPlugin.cpp index ad27c0edc0..597364bf53 100644 --- a/Modules/US/USHardwareTelemed/mitkUSTelemedScanConverterPlugin.cpp +++ b/Modules/US/USHardwareTelemed/mitkUSTelemedScanConverterPlugin.cpp @@ -1,149 +1,147 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkUSTelemedScanConverterPlugin.h" #include "mitkImageWriteAccessor.h" USTelemedScanConverterPlugin::USTelemedScanConverterPlugin( ) - : m_Plugin(nullptr), m_OutputImage(nullptr), m_OutputImageMutex(nullptr) + : m_Plugin(nullptr), m_OutputImage(nullptr) { } USTelemedScanConverterPlugin::~USTelemedScanConverterPlugin( ) { ReleasePlugin(); } // -- internal Telemed API function HRESULT __stdcall USTelemedScanConverterPlugin::QueryInterface(const IID& iid, void** ppv) { reinterpret_cast(*ppv)->AddRef() ; return S_OK ; } // -- internal Telemed API function ULONG __stdcall USTelemedScanConverterPlugin::AddRef() { return InterlockedIncrement(&m_cRef) ; } // -- internal Telemed API function ULONG __stdcall USTelemedScanConverterPlugin::Release() { if (InterlockedDecrement(&m_cRef) == 0) { delete this ; return 0 ; } return m_cRef ; } STDMETHODIMP USTelemedScanConverterPlugin::InterimOutBufferCB ( PBYTE pBufferInterim, int nInterimBufferLen, PBYTE pBufferOut, int nOutBufferLen, int nOutX1, int nOutY1, int nOutX2, int nOutY2 ) { if ( m_OutputImage.IsNull() ) { return S_FALSE; }; - - if ( m_OutputImageMutex.IsNotNull() ) { m_OutputImageMutex->Lock(); } - + m_OutputImageMutex->lock(); // initialize mitk::Image with given image size on the first time if ( ! m_OutputImage->IsInitialized() ) { unsigned int dim[]={static_cast(abs(nOutX2 - nOutX1)), static_cast(abs(nOutY2 - nOutY1))}; // image dimensions m_OutputImage->Initialize(mitk::MakeScalarPixelType(), 2, dim); } // lock the image for writing an copy the given buffer into the image then m_OutputImage->SetSlice(pBufferOut); - if ( m_OutputImageMutex.IsNotNull() ) { m_OutputImageMutex->Unlock(); } + m_OutputImageMutex->unlock(); return S_OK; } void USTelemedScanConverterPlugin::ReleasePlugin() { if (m_Plugin != nullptr) { // remove this callback from Telemed API plugin m_Plugin->SetCallback(nullptr,USPC_BUFFER_INTERIM_OUTPUT); } } -void USTelemedScanConverterPlugin::SetOutputImage(mitk::Image::Pointer outputImage, itk::FastMutexLock::Pointer outputImageMutex) +void USTelemedScanConverterPlugin::SetOutputImage(mitk::Image::Pointer outputImage, std::mutex* outputImageMutex) { m_OutputImage = outputImage; m_OutputImageMutex = outputImageMutex; } STDMETHODIMP USTelemedScanConverterPlugin::SetScanConverterPlugin(IDispatch* plugin) { // make sure that there is no scan converter plugin registered already this->ReleasePlugin(); HRESULT hr; // it is ok to call this method with a nullptr plugin to remove // a previous callback if (plugin == nullptr) { MITK_INFO("IUsgfwScanConverterPluginCB")("ScanConverterPlugin") << "nullptr plugin set to the scan converter. The callback for the previous plugin is removed now."; return S_OK; } // get Telemed API plugin from the COM library Usgfw2Lib::IUsgScanConverterPlugin* tmp_plugin; hr = plugin->QueryInterface(__uuidof(Usgfw2Lib::IUsgScanConverterPlugin), (void**)&tmp_plugin); if (FAILED(hr)) { MITK_WARN("IUsgfwScanConverterPluginCB")("ScanConverterPlugin") << "Could not query com interface for IUsgScanConverterPlugin (" << hr << ")."; return hr; } // get the converter for scan lines from the COM library and // save it as a member attribute hr = tmp_plugin->get_ScanConverter((IUnknown**)&m_Plugin); if (FAILED(hr)) { MITK_WARN("IUsgfwScanConverterPluginCB")("ScanConverterPlugin") << "Could not get ScanConverter from plugin (" << hr << ")."; return hr; } SAFE_RELEASE(tmp_plugin); // now the callback can be set -> interface functions of this // object will be called from now on when new image data is // available hr = m_Plugin->SetCallback(this,USPC_BUFFER_INTERIM_OUTPUT); if (FAILED(hr)) { MITK_WARN("IUsgfwScanConverterPluginCB")("ScanConverterPlugin") << "Could not set callback for plugin (" << hr << ")."; return hr; } return S_OK; } diff --git a/Modules/US/USHardwareTelemed/mitkUSTelemedScanConverterPlugin.h b/Modules/US/USHardwareTelemed/mitkUSTelemedScanConverterPlugin.h index c4ec8e8235..2ad357451d 100644 --- a/Modules/US/USHardwareTelemed/mitkUSTelemedScanConverterPlugin.h +++ b/Modules/US/USHardwareTelemed/mitkUSTelemedScanConverterPlugin.h @@ -1,166 +1,167 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef MITKUSTelemedScanConverterPlugin_H_HEADER_INCLUDED_ #define MITKUSTelemedScanConverterPlugin_H_HEADER_INCLUDED_ #include #include #include #include #include +#include #include "mitkUSTelemedSDKHeader.h" #include "mitkImage.h" -#include "itkFastMutexLock.h" + /** * \brief Telemed API plugin for getting images from scan lines. * Implements a COM interface whereat only the function InterimOutBufferCB * is used for copying given image buffer into a mitk::Image. * * A pointer to this mitk::Image must be set by calling * mitk::USTelemedScanConverterPlugin::SetOutputImage() first. * The image content is then updated every time the Telemed API calls * the implemented callback function of this class. * * For more infomration about the implemented COM interface refer to the * Telemed API documentation. */ class USTelemedScanConverterPlugin : public IUsgfwScanConverterPluginCB { public: USTelemedScanConverterPlugin( ); ~USTelemedScanConverterPlugin( ); // internal functions for Telemed API virtual HRESULT __stdcall QueryInterface(const IID& iid,void** ppv); virtual ULONG __stdcall AddRef(); virtual ULONG __stdcall Release(); /** * Setter for a pointer to a mitk::Image in which the current * image buffer from the Telemed API will be stored at every * API callback. This function must be called before image data * can be got from this class. * A pointer to a mutex can be set in addition. This mutex will * be locked on every writing to the given image. */ - void SetOutputImage(mitk::Image::Pointer outputImage, itk::FastMutexLock::Pointer outputImageMutex = 0); + void SetOutputImage(mitk::Image::Pointer outputImage, std::mutex* outputImageMutex); // receives pointers to input and output media samples STDMETHOD(SampleCB) ( IMediaSample *pSampleIn, IMediaSample *pSampleOut, int nOutX1, int nOutY1, int nOutX2, int nOutY2 ) {return S_OK;} // receives pointers to input and output sample buffers STDMETHOD(BufferCB) ( PBYTE pBufferIn, int nInBufferLen, PBYTE pBufferOut, int nOutBufferLen, int nOutX1, int nOutY1, int nOutX2, int nOutY2 ) {return S_OK;} // receives pointers to input and intermediate sample buffers STDMETHOD(InInterimBufferCB) ( PBYTE pBufferIn, int nInBufferLen, PBYTE pBufferInterim, int nInterimBufferLen, int nOutX1, int nOutY1, int nOutX2, int nOutY2 ) {return S_OK;} // receves pointers to input media sample and intermediatesample buffer STDMETHOD(InInterimSampleCB) ( IMediaSample *pSampleIn, PBYTE pBufferInterim, int nInterimBufferLen, int nOutX1, int nOutY1, int nOutX2, int nOutY2 ) {return S_OK;} // receives pointers to output and intermediate sample buffers STDMETHOD(InterimOutBufferCB) ( PBYTE pBufferInterim, int nInterimBufferLen, PBYTE pBufferOut, int nOutBufferLen, int nOutX1, int nOutY1, int nOutX2, int nOutY2 ); // receives pointers to output media sample and intermediate sample buffer STDMETHOD(InterimOutSampleCB) ( PBYTE pBufferInterim, int nInterimBufferLen, IMediaSample *pSampleIn, int nOutX1, int nOutY1, int nOutX2, int nOutY2 ) {return S_OK;} // receives conversion parameter change pin index // if parameter is negative parameter was changed by some filter interface STDMETHOD(ParameterCB) ( int nPin ) { return S_OK; } STDMETHOD(SetScanConverterPlugin)(IDispatch* plugin); //STDMETHOD(getSource)(LONG* plugin); protected: /** * Remove Telemed API callback and release and delete m_Plugin attribute. */ void ReleasePlugin( ); /** * Telemed API object for handling callbacks on new image data. */ IUsgfwScanConverterPlugin* m_Plugin; /** * Pointer to mitk::Image in which the current image buffer * from the Telemed API will be stored at every API callback. */ mitk::Image::Pointer m_OutputImage; /** * Mutex for the output image. Has to be set together with the * output image via SetOutputImage(). */ - itk::FastMutexLock::Pointer m_OutputImageMutex; + std::mutex* m_OutputImageMutex; private: long m_cRef ; }; #endif // MITKUSTelemedScanConverterPlugin_H_HEADER_INCLUDED_