Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkUSTelemedDevice.cpp
Go to the documentation of this file.
1 /*===================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 
17 #include "mitkUSTelemedDevice.h"
18 
19 #include "mitkUSTelemedSDKHeader.h"
20 
21 mitk::USTelemedDevice::USTelemedDevice(std::string manufacturer, std::string model)
22 : mitk::USDevice(manufacturer, model),
23 m_ControlsProbes(mitk::USTelemedProbesControls::New(this)),
24 m_ControlsBMode(mitk::USTelemedBModeControls::New(this)),
25 m_ControlsDoppler(mitk::USTelemedDopplerControls::New(this)),
26 m_ImageSource(mitk::USTelemedImageSource::New()), m_UsgMainInterface(0),
27 m_Probe(0), m_UsgDataView(0), m_ProbesCollection(0)
28 {
29  SetNumberOfOutputs(1);
30  SetNthOutput(0, this->MakeOutput(0));
31 }
32 
34 {
35 }
36 
38 {
39  return "org.mitk.modules.us.USTelemedDevice";
40 }
41 
43 {
44  return m_ControlsBMode.GetPointer();
45 }
46 
48 {
49  return m_ControlsProbes.GetPointer();
50 };
51 
53 {
54  return m_ControlsDoppler.GetPointer();
55 };
56 
58 {
59  CoInitialize(NULL); // initialize COM library
60 
61  return true;
62 }
63 
65 {
66  // create main Telemed API COM library object
67  HRESULT hr;
68 
69  hr = CoCreateInstance(Usgfw2Lib::CLSID_Usgfw2, NULL, CLSCTX_INPROC_SERVER, Usgfw2Lib::IID_IUsgfw2,(LPVOID*) &m_UsgMainInterface);
70  if (FAILED(hr))
71  {
72  SAFE_RELEASE(m_UsgMainInterface);
73  MITK_ERROR("USDevice")("USTelemedDevice") << "Error at connecting to ultrasound device (" << hr << ").";
74  return false;
75  }
76 
77  this->ConnectDeviceChangeSink();
78 
79  return true;
80 }
81 
83 {
84  // control objects cannot be active anymore
85  m_ControlsBMode->SetIsActive(false);
86  m_ControlsDoppler->SetIsActive(false);
87  m_ControlsProbes->SetIsActive(false);
88 
89  ReleaseUsgControls();
90 
91  return true;
92 }
93 
95 {
96  // probe controls are available now
97  m_ControlsProbes->SetIsActive(true);
98 
99  if ( m_ControlsProbes->GetProbesCount() < 1 )
100  {
101  MITK_WARN("USDevice")("USTelemedDevice") << "No probe found.";
102  return false;
103  }
104 
105  // select first probe as a default
106  m_ControlsProbes->SelectProbe(0);
107 
108  // set scan mode b as default for activation -
109  // control interfaces can override this later
110  HRESULT hr = m_UsgDataView->put_ScanMode(Usgfw2Lib::SCAN_MODE_B);
111  if (FAILED(hr))
112  {
113  MITK_ERROR("USDevice")("USTelemedDevice") << "Could not set scan mode b (" << hr << ").";
114  return false;
115  }
116 
117  // start ultrasound scanning with selected scan mode
118  hr = m_UsgDataView->put_ScanState(Usgfw2Lib::SCAN_STATE_RUN);
119  if (FAILED(hr))
120  {
121  MITK_ERROR("USDevice")("USTelemedDevice") << "Start scanning failed (" << hr << ").";
122  return false;
123  }
124 
125  m_ControlsBMode->ReinitializeControls();
126 
127  return true;
128 }
129 
131 {
132  this->StopScanning();
133  return true;
134 }
135 
137 {
138  if ( freeze )
139  {
140  m_UsgDataView->put_ScanState(Usgfw2Lib::SCAN_STATE_FREEZE);
141  }
142  else
143  {
144  m_UsgDataView->put_ScanState(Usgfw2Lib::SCAN_STATE_RUN);
145  }
146 }
147 
149 {
150  return m_ImageSource.GetPointer();
151 }
152 
154 {
155  if (m_UsgDataView) { this->StopScanning(); };
156 
157  SAFE_RELEASE(m_UsgMainInterface);
158  SAFE_RELEASE(m_Probe);
159  SAFE_RELEASE(m_UsgDataView);
160  SAFE_RELEASE(m_ProbesCollection);
161 }
162 
164 {
165  if ( ! m_UsgDataView )
166  {
167  MITK_WARN("USDevice")("USTelemedDevice") << "Cannot stop scanning as Telemed Data View is null.";
168  return;
169  }
170 
171  HRESULT hr;
172  hr = m_UsgDataView->put_ScanState(Usgfw2Lib::SCAN_STATE_STOP);
173 
174  if (FAILED(hr))
175  {
176  MITK_ERROR("USDevice")("USTelemedDevice") << "Stop scanning failed (" << hr << ").";
177  mitkThrow() << "Stop scanning failed (" << hr << ").";
178  }
179 }
180 
182 {
183  return m_UsgMainInterface;
184 }
185 
186 void mitk::USTelemedDevice::SetActiveDataView(Usgfw2Lib::IUsgDataView* usgDataView)
187 {
188  // do nothing if the usg data view hasn't changed
189  if ( m_UsgDataView != usgDataView )
190  {
191  // scan converter plugin is connected to IUsgDataView -> a new plugin
192  // must be created when changing IUsgDataView
193  m_UsgDataView = usgDataView;
194  if ( ! m_ImageSource->CreateAndConnectConverterPlugin(m_UsgDataView, Usgfw2Lib::SCAN_MODE_B)) { return; }
195 
196  // b mode control object must know about active data view
197  m_ControlsBMode->SetUsgDataView(m_UsgDataView);
198  }
199 }
200 
202 {
203  IConnectionPointContainer* cpc = NULL;
204  HRESULT hr = m_UsgMainInterface->QueryInterface(IID_IConnectionPointContainer, (void**)&cpc);
205  if (hr != S_OK)
206  cpc = NULL;
207 
208  if (cpc != NULL)
209  hr = cpc->FindConnectionPoint(Usgfw2Lib::IID_IUsgDeviceChangeSink, &m_UsgDeviceChangeCpnt);
210 
211  if (hr != S_OK)
212  {
213  m_UsgDeviceChangeCpnt = NULL;
214  m_UsgDeviceChangeCpntCookie = 0;
215  }
216  SAFE_RELEASE(cpc);
217 
218  if (m_UsgDeviceChangeCpnt != NULL)
219  hr = m_UsgDeviceChangeCpnt->Advise((IUnknown*)((Usgfw2Lib::IUsgDeviceChangeSink*)this), &m_UsgDeviceChangeCpntCookie);
220 }
221 
222 // --- Methods for Telemed API Interfaces
223 
224 HRESULT __stdcall mitk::USTelemedDevice::raw_OnBeamformerArrive(IUnknown *pUsgBeamformer, ULONG *reserved)
225 {
226  this->Connect();
227 
228  return S_OK;
229 }
230 
231 HRESULT __stdcall mitk::USTelemedDevice::raw_OnBeamformerRemove(IUnknown *pUsgBeamformer, ULONG *reserved)
232 {
233  if ( this->GetIsActive() ) { this->Deactivate(); }
234 
235  this->Disconnect();
236 
237  return S_OK;
238 }
239 
240 HRESULT __stdcall mitk::USTelemedDevice::raw_OnProbeArrive(IUnknown*, ULONG* probeIndex)
241 {
242  m_ControlsProbes->ProbeAdded(static_cast<unsigned int>(*probeIndex));
243 
244  this->Activate();
245 
246  return S_OK;
247 };
248 
249 HRESULT __stdcall mitk::USTelemedDevice::raw_OnProbeRemove(IUnknown*, ULONG* probeIndex)
250 {
251  m_ControlsProbes->ProbeRemoved(static_cast<unsigned int>(*probeIndex));
252 
253  if ( this->GetIsActive() ) { this->Deactivate(); }
254 
255  return S_OK;
256 };
257 
258 STDMETHODIMP_(ULONG) mitk::USTelemedDevice::AddRef()
259 {
260  ++m_RefCount;
261  return m_RefCount;
262 }
263 
264 STDMETHODIMP_(ULONG) mitk::USTelemedDevice::Release()
265 {
266  --m_RefCount;
267  return m_RefCount;
268 }
269 
270 STDMETHODIMP mitk::USTelemedDevice::QueryInterface(REFIID riid, void** ppv)
271 {
272  if (riid == IID_IUnknown || riid == Usgfw2Lib::IID_IUsgDeviceChangeSink)
273  {
274  *ppv = (IUsgDeviceChangeSink*)this;
275  return S_OK;
276  }
277  if (riid == IID_IDispatch)
278  {
279  *ppv = (IDispatch*)this;
280  return S_OK;
281  }
282  return E_NOINTERFACE;
283 }
284 
286 {
287  if (pctinfo == NULL) return E_INVALIDARG;
288  *pctinfo = 0;
289  return S_OK;
290 }
291 
292 HRESULT mitk::USTelemedDevice::GetTypeInfo(UINT itinfo, LCID lcid, ITypeInfo** pptinfo)
293 {
294  if (pptinfo == NULL) return E_INVALIDARG;
295  *pptinfo = NULL;
296  if(itinfo != 0) return DISP_E_BADINDEX;
297  return S_OK;
298 }
299 
300 HRESULT mitk::USTelemedDevice::GetIDsOfNames(const IID &riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgdispid)
301 {
302  // this is not used - must use the same fixed dispid's from Usgfw2 idl file
303  return S_OK;
304 }
305 
306 HRESULT mitk::USTelemedDevice::Invoke(DISPID dispIdMember, const IID &riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
307 {
308  if ( (dispIdMember >= 1) && (dispIdMember <= 6) )
309  {
310  if (pDispParams->cArgs != 2) // we need 2 arguments
311  return S_OK;
312 
313  IUnknown *unkn = NULL;
314  ULONG *res = NULL;
315 
316  VARIANTARG* p1;
317  VARIANTARG* p;
318  p1 = pDispParams->rgvarg;
319 
320  p = p1;
321  if (p->vt == (VT_BYREF|VT_UI4))
322  res = p->pulVal;
323  p1++;
324 
325  p = p1;
326  if (p->vt == VT_UNKNOWN)
327  unkn = (IUnknown*)(p->punkVal);
328 
329  if (dispIdMember == 1)
330  OnProbeArrive(unkn, res);
331  else if (dispIdMember == 2)
332  OnBeamformerArrive(unkn, res);
333  else if (dispIdMember == 3)
334  OnProbeRemove(unkn, res);
335  else if (dispIdMember == 4)
336  OnBeamformerRemove(unkn, res);
337  else if (dispIdMember == 5)
338  OnProbeStateChanged(unkn, res);
339  else if (dispIdMember == 6)
340  OnBeamformerStateChanged(unkn, res);
341  }
342 
343  return S_OK;
344 }
virtual bool OnConnection()
Is called during the connection process. Connect to the Telemed API and try to get available probes f...
A device holds information about it's model, make and the connected probes. It is the common super cl...
Definition: mitkUSDevice.h:77
itk::SmartPointer< Self > Pointer
virtual itk::DataObject::Pointer MakeOutput(DataObjectPointerArraySizeType idx) override
Make a DataObject of the correct type to used as the specified output.
STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
#define MITK_ERROR
Definition: mitkLogMacros.h:24
virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames(const IID &riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgdispid)
DataCollection - Class to facilitate loading/accessing structured data.
Implementation of mitk::USControlInterfaceProbes for Telemed ultrasound devices. See documentation of...
virtual HRESULT __stdcall raw_OnBeamformerRemove(IUnknown *pUsgBeamformer, ULONG *reserved)
Usgfw2Lib::IUsgfw2 * GetUsgMainInterface()
Getter for main Telemed API object. This method is for being called by Telemed control interfaces...
Implementation of mitk::USImageSource for Telemed API devices. The method mitk::USImageSource::GetNex...
virtual HRESULT STDMETHODCALLTYPE GetTypeInfo(UINT itinfo, LCID lcid, ITypeInfo **pptinfo)
#define MITK_WARN
Definition: mitkLogMacros.h:23
virtual USControlInterfaceProbes::Pointer GetControlInterfaceProbes()
Default getter for the probes control interface. Has to be implemented in a subclass if a probes cont...
virtual HRESULT __stdcall raw_OnProbeRemove(IUnknown *pUsgProbe, ULONG *reserved)
#define mitkThrow()
virtual bool OnDeactivation()
Is called during the deactivation process. After a call to this method the device is connected...
USTelemedDevice(std::string manufacturer, std::string model)
virtual std::string GetDeviceClass()
Returns the class of the device.
virtual HRESULT STDMETHODCALLTYPE Invoke(DISPID dispIdMember, const IID &riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
#define SAFE_RELEASE(x)
virtual HRESULT __stdcall raw_OnProbeArrive(IUnknown *pUsgProbe, ULONG *reserved)
USImageSource::Pointer GetUSImageSource()
void SetActiveDataView(Usgfw2Lib::IUsgDataView *)
Changes active IUsgDataView of the device. This method is for being called by Telemed control interfa...
virtual USControlInterfaceDoppler::Pointer GetControlInterfaceDoppler()
Default getter for the doppler control interface. Has to be implemented in a subclass if a doppler co...
virtual HRESULT STDMETHODCALLTYPE GetTypeInfoCount(UINT *pctinfo)
virtual bool OnActivation()
Is called during the activation process. After this method is finished, the device is generating imag...
virtual void OnFreeze(bool freeze)
Changes scan state of the device if freeze is toggeled in mitk::USDevice.
virtual bool OnDisconnection()
Is called during the disconnection process. Deactivate and remove all Telemed API controls...
Implementation of mitk::USControlInterfaceBMode for Telemed ultrasound devices. See documentation of ...
STDMETHODIMP_(ULONG) mitk
virtual bool OnInitialization()
Is called during the initialization process. There is nothing done on the initialization of a mik::US...
void StopScanning()
Stop ultrasound scanning by Telemed API call.
virtual USControlInterfaceBMode::Pointer GetControlInterfaceBMode()
Default getter for the b mode control interface. Has to be implemented in a subclass if a b mode cont...
virtual HRESULT __stdcall raw_OnBeamformerArrive(IUnknown *pUsgBeamformer, ULONG *reserved)
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.
Implementation of mitk::USControlInterfaceDoppler for Telemed ultrasound devices. See documentation o...