From 37f4457655595269059d3a3b76480ddc48b3308e Mon Sep 17 00:00:00 2001 From: Kyle Sunderland Date: Tue, 8 Jul 2025 11:55:45 -0400 Subject: [PATCH] ENH: Add interface for specifying camera control parameters with Microsoft Media foundation device This commit creates a generic base class vtkPlusParameters from vtkPlusUsImagingParameters that is now used for both ultrasound and camera control parameters. The new camera control parameters class contains the ability to set camera properties from the config file, and eventually through commands. Camera control properties are: - PanDegrees - TiltDegrees - RollDegrees - ZoomMm - IrisFStop - ExposureLog2Seconds - AutoExposure - FocusMm - AutoFocus Example config file element: ``` ``` Not that not all parameters will be adjustable for all cameras. --- src/PlusDataCollection/CMakeLists.txt | 4 + .../vtkPlusMmfVideoSource.cxx | 196 ++++++++++++++++- .../vtkPlusMmfVideoSource.h | 6 + .../vtkPlusCameraControlParameters.cxx | 170 +++++++++++++++ .../vtkPlusCameraControlParameters.h | 114 ++++++++++ src/PlusDataCollection/vtkPlusParameters.cxx | 204 ++++++++++++++++++ src/PlusDataCollection/vtkPlusParameters.h | 148 +++++++++++++ .../vtkPlusUsImagingParameters.cxx | 179 +-------------- .../vtkPlusUsImagingParameters.h | 116 +--------- 9 files changed, 840 insertions(+), 297 deletions(-) create mode 100644 src/PlusDataCollection/vtkPlusCameraControlParameters.cxx create mode 100644 src/PlusDataCollection/vtkPlusCameraControlParameters.h create mode 100644 src/PlusDataCollection/vtkPlusParameters.cxx create mode 100644 src/PlusDataCollection/vtkPlusParameters.h diff --git a/src/PlusDataCollection/CMakeLists.txt b/src/PlusDataCollection/CMakeLists.txt index d01761757..943e1a255 100644 --- a/src/PlusDataCollection/CMakeLists.txt +++ b/src/PlusDataCollection/CMakeLists.txt @@ -130,6 +130,8 @@ SET(Common_SRCS vtkFcsvReader.cxx vtkFcsvWriter.cxx vtkPlusBuffer.cxx + vtkPlusParameters.cxx + vtkPlusCameraControlParameters.cxx vtkPlusUsImagingParameters.cxx ) SET(Virtual_SRCS @@ -172,6 +174,8 @@ SET(Common_HDRS vtkFcsvReader.h vtkFcsvWriter.h vtkPlusBuffer.h + vtkPlusParameters.h + vtkPlusCameraControlParameters.h vtkPlusUsImagingParameters.h ) SET(Miscellaneous_HDRS diff --git a/src/PlusDataCollection/MicrosoftMediaFoundation/vtkPlusMmfVideoSource.cxx b/src/PlusDataCollection/MicrosoftMediaFoundation/vtkPlusMmfVideoSource.cxx index 92295144f..552c639a5 100644 --- a/src/PlusDataCollection/MicrosoftMediaFoundation/vtkPlusMmfVideoSource.cxx +++ b/src/PlusDataCollection/MicrosoftMediaFoundation/vtkPlusMmfVideoSource.cxx @@ -15,6 +15,7 @@ Authors include: Adam Rankin // Local includes #include "PlusConfigure.h" #include "PixelCodec.h" +#include "vtkPlusCameraControlParameters.h" #include "vtkPlusChannel.h" #include "vtkPlusDataSource.h" #include "vtkPlusMmfVideoSource.h" @@ -36,6 +37,7 @@ Authors include: Adam Rankin // Windows includes #include #include +#include #include #include @@ -44,7 +46,7 @@ Authors include: Adam Rankin namespace { const unsigned int DEFAULT_DEVICE_ID = 0; - const FrameSizeType DEFAULT_FRAME_SIZE = {640, 480, 1}; + const FrameSizeType DEFAULT_FRAME_SIZE = { 640, 480, 1 }; const double DEFAULT_ACQUISITION_RATE = 30; const std::wstring DEFAULT_PIXEL_TYPE_NAME = L"YUY2"; const GUID DEFAULT_PIXEL_TYPE = MFVideoFormat_YUY2; // see http://msdn.microsoft.com/en-us/library/windows/desktop/aa370819(v=vs.85).aspx @@ -174,7 +176,7 @@ STDMETHODIMP MmfVideoSourceReader::OnReadSample(HRESULT hrStatus, DWORD dwStream UINT32 actualHeight = 0; ::MFGetAttributeSize(pType, MF_MT_FRAME_SIZE, &actualWidth, &actualHeight); if (actualWidth != this->PlusDevice->ActiveVideoFormat.FrameSize[0] || - actualHeight != this->PlusDevice->ActiveVideoFormat.FrameSize[1]) + actualHeight != this->PlusDevice->ActiveVideoFormat.FrameSize[1]) { LOG_ERROR("Unexpected frame size: " << actualWidth << "x" << actualHeight << " (expected: " << this->PlusDevice->ActiveVideoFormat.FrameSize[0] << "x" << this->PlusDevice->ActiveVideoFormat.FrameSize[1] << ")"); return S_FALSE; @@ -246,6 +248,7 @@ vtkStandardNewMacro(vtkPlusMmfVideoSource); vtkPlusMmfVideoSource::vtkPlusMmfVideoSource() : FrameIndex(0) , Mutex(vtkSmartPointer::New()) + , CameraControlParameters(vtkSmartPointer::New()) { this->MmfSourceReader = new MmfVideoSourceReader(this); this->RequireImageOrientationInConfiguration = true; @@ -278,6 +281,8 @@ void vtkPlusMmfVideoSource::PrintSelf(ostream& os, vtkIndent indent) this->Superclass::PrintSelf(os, indent); os << indent << "FrameIndex: " << (this->FrameIndex ? "On\n" : "Off\n"); + + this->CameraControlParameters->PrintSelf(os, indent.GetNextIndent()); } //---------------------------------------------------------------------------- @@ -305,12 +310,12 @@ PlusStatus vtkPlusMmfVideoSource::InternalConnect() } if (!MfVideoCapture::MediaFoundationVideoCaptureApi::GetInstance().SetupDevice(this->RequestedVideoFormat.DeviceId, this->RequestedVideoFormat.StreamIndex, - this->RequestedVideoFormat.FrameSize[0], this->RequestedVideoFormat.FrameSize[1], this->AcquisitionRate, pixelFormat)) + this->RequestedVideoFormat.FrameSize[0], this->RequestedVideoFormat.FrameSize[1], this->AcquisitionRate, pixelFormat)) { LOG_WARNING_W("Unable to init capture device with requested details:" - << " device ID: " << this->RequestedVideoFormat.DeviceId << " (" << GetRequestedDeviceName() << ") stream " << this->RequestedVideoFormat.StreamIndex - << ", " << this->RequestedVideoFormat.FrameSize[0] << "x" << this->RequestedVideoFormat.FrameSize[1] - << ", " << this->AcquisitionRate << "Hz, " << this->ActiveVideoFormat.PixelFormatName); + << " device ID: " << this->RequestedVideoFormat.DeviceId << " (" << GetRequestedDeviceName() << ") stream " << this->RequestedVideoFormat.StreamIndex + << ", " << this->RequestedVideoFormat.FrameSize[0] << "x" << this->RequestedVideoFormat.FrameSize[1] + << ", " << this->AcquisitionRate << "Hz, " << this->ActiveVideoFormat.PixelFormatName); LogListOfCaptureVideoFormats(this->RequestedVideoFormat.DeviceId); @@ -328,9 +333,9 @@ PlusStatus vtkPlusMmfVideoSource::InternalConnect() this->ActiveVideoFormat.PixelFormatName = DEFAULT_PIXEL_TYPE_NAME; LOG_INFO_W("Backing up to connecting with default capture settings:" - << " device ID: " << this->ActiveVideoFormat.DeviceId << " (" << GetActiveDeviceName() << ")" - << ", " << this->ActiveVideoFormat.FrameSize[0] << "x" << this->ActiveVideoFormat.FrameSize[1] - << ", " << DEFAULT_ACQUISITION_RATE << "Hz, " << this->ActiveVideoFormat.PixelFormatName); + << " device ID: " << this->ActiveVideoFormat.DeviceId << " (" << GetActiveDeviceName() << ")" + << ", " << this->ActiveVideoFormat.FrameSize[0] << "x" << this->ActiveVideoFormat.FrameSize[1] + << ", " << DEFAULT_ACQUISITION_RATE << "Hz, " << this->ActiveVideoFormat.PixelFormatName); } this->MmfSourceReader->CaptureSource = MfVideoCapture::MediaFoundationVideoCaptureApi::GetInstance().GetMediaSource(this->ActiveVideoFormat.DeviceId); @@ -343,6 +348,12 @@ PlusStatus vtkPlusMmfVideoSource::InternalConnect() unsigned int frameRate = MfVideoCapture::MediaFoundationVideoCaptureApi::GetInstance().GetFrameRate(this->ActiveVideoFormat.DeviceId); LOG_DEBUG_W("vtkPlusMmfVideoSource connected to device '" << GetActiveDeviceName() << "' at frame rate of " << frameRate << "Hz"); + if (this->InternalApplyCameraControlParameterChange() == PLUS_FAIL) + { + LOG_ERROR("Failed to change imaging parameters in the device"); + return PLUS_FAIL; + } + this->FrameIndex = 0; return PLUS_SUCCESS; @@ -394,7 +405,7 @@ PlusStatus vtkPlusMmfVideoSource::InternalStartRecording() if (FAILED(hr)) { LOG_WARNING_W("Unable to set SourceReader output to requested format: " << this->RequestedVideoFormat.PixelFormatName - << ". Using device default."); + << ". Using device default."); } SafeRelease(&pDecodeType); @@ -485,7 +496,7 @@ PlusStatus vtkPlusMmfVideoSource::ReadConfiguration(vtkXMLDataElement* rootConfi this->RequestedVideoFormat.StreamIndex = (DWORD)streamIndex; } - int requestedFrameSize[2] = {static_cast(DEFAULT_FRAME_SIZE[0]), static_cast(DEFAULT_FRAME_SIZE[1])}; + int requestedFrameSize[2] = { static_cast(DEFAULT_FRAME_SIZE[0]), static_cast(DEFAULT_FRAME_SIZE[1]) }; if (deviceConfig->GetVectorAttribute("FrameSize", 2, requestedFrameSize)) { if (requestedFrameSize[0] < 0 || requestedFrameSize[1] < 0) @@ -505,6 +516,12 @@ PlusStatus vtkPlusMmfVideoSource::ReadConfiguration(vtkXMLDataElement* rootConfi this->RequestedVideoFormat.PixelFormatName = std::wstring(attr.begin(), attr.end()); } + XML_FIND_NESTED_ELEMENT_OPTIONAL(cameraParameters, deviceConfig, vtkPlusCameraControlParameters::CAMERA_CONTROL_XML_ELEMENT_TAG); + if (cameraParameters != NULL) + { + this->CameraControlParameters->ReadConfiguration(deviceConfig); + } + return PLUS_SUCCESS; } @@ -527,6 +544,8 @@ PlusStatus vtkPlusMmfVideoSource::WriteConfiguration(vtkXMLDataElement* rootConf auto attr = std::string(this->RequestedVideoFormat.PixelFormatName.begin(), this->RequestedVideoFormat.PixelFormatName.end()); deviceConfig->SetAttribute("VideoFormat", attr.c_str()); + this->CameraControlParameters->WriteConfiguration(deviceConfig); + return PLUS_SUCCESS; } @@ -725,4 +744,159 @@ void vtkPlusMmfVideoSource::LogListOfCaptureDevices() std::wstring vtkPlusMmfVideoSource::GetCaptureDeviceName(unsigned int deviceId) { return MfVideoCapture::MediaFoundationVideoCaptureApi::GetInstance().GetCaptureDeviceName(deviceId); +} + +//---------------------------------------------------------------------------- +PlusStatus vtkPlusMmfVideoSource::InternalApplyCameraControlParameterChange() +{ + if (this->MmfSourceReader->CaptureSource == NULL) + { + LOG_ERROR("Cannot apply camera control parameter change, capture source is not initialized"); + return PLUS_FAIL; + } + + MfVideoCapture::CaptureDeviceParameters parameters = + MfVideoCapture::MediaFoundationVideoCaptureApi::GetInstance().GetParameters(this->ActiveVideoFormat.DeviceId); + + //////////////////////////// + // Pan + if (this->CameraControlParameters->IsSet(vtkPlusCameraControlParameters::KEY_PAN_DEGREES) + && this->CameraControlParameters->IsPending(vtkPlusCameraControlParameters::KEY_PAN_DEGREES)) + { + double panDegrees = 0.0; + if (this->CameraControlParameters->GetPanDegrees(panDegrees) != PLUS_SUCCESS) + { + LOG_ERROR("Failed to get pan camera control parameter"); + return PLUS_FAIL; + } + parameters.CameraControlParameters[MfVideoCapture::CaptureDeviceParameters::Pan].CurrentValue = panDegrees; + this->CameraControlParameters->SetPending(vtkPlusCameraControlParameters::KEY_PAN_DEGREES, false); + } + + //////////////////////////// + // Tilt + if (this->CameraControlParameters->IsSet(vtkPlusCameraControlParameters::KEY_TILT_DEGREES) + && this->CameraControlParameters->IsPending(vtkPlusCameraControlParameters::KEY_TILT_DEGREES)) + { + double tiltDegrees = 0.0; + if (this->CameraControlParameters->GetTiltDegrees(tiltDegrees) != PLUS_SUCCESS) + { + LOG_ERROR("Failed to get tilt camera control parameter"); + return PLUS_FAIL; + } + parameters.CameraControlParameters[MfVideoCapture::CaptureDeviceParameters::Tilt].CurrentValue = tiltDegrees; + this->CameraControlParameters->SetPending(vtkPlusCameraControlParameters::KEY_TILT_DEGREES, false); + } + + //////////////////////////// + // Roll + if (this->CameraControlParameters->IsSet(vtkPlusCameraControlParameters::KEY_ROLL_DEGREES) + && this->CameraControlParameters->IsPending(vtkPlusCameraControlParameters::KEY_ROLL_DEGREES)) + { + double rollDegrees = 0.0; + if (this->CameraControlParameters->GetRollDegrees(rollDegrees) != PLUS_SUCCESS) + { + LOG_ERROR("Failed to get roll camera control parameter"); + return PLUS_FAIL; + } + parameters.CameraControlParameters[MfVideoCapture::CaptureDeviceParameters::Roll].CurrentValue = rollDegrees; + this->CameraControlParameters->SetPending(vtkPlusCameraControlParameters::KEY_ROLL_DEGREES, false); + } + + //////////////////////////// + // Zoom + if (this->CameraControlParameters->IsSet(vtkPlusCameraControlParameters::KEY_ZOOM_MM) + && this->CameraControlParameters->IsPending(vtkPlusCameraControlParameters::KEY_ZOOM_MM)) + { + double zoomMm = 0.0; + if (this->CameraControlParameters->GetZoomMm(zoomMm) != PLUS_SUCCESS) + { + LOG_ERROR("Failed to get zoom camera control parameter"); + return PLUS_FAIL; + } + parameters.CameraControlParameters[MfVideoCapture::CaptureDeviceParameters::Zoom].CurrentValue = zoomMm; + this->CameraControlParameters->SetPending(vtkPlusCameraControlParameters::KEY_ZOOM_MM, false); + } + + //////////////////////////// + // Iris + if (this->CameraControlParameters->IsSet(vtkPlusCameraControlParameters::KEY_IRIS_FSTOP) + && this->CameraControlParameters->IsPending(vtkPlusCameraControlParameters::KEY_IRIS_FSTOP)) + { + int irisFStop = 0; + if (this->CameraControlParameters->GetIrisFStop(irisFStop) != PLUS_SUCCESS) + { + LOG_ERROR("Failed to get iris camera control parameter"); + return PLUS_FAIL; + } + parameters.CameraControlParameters[MfVideoCapture::CaptureDeviceParameters::Iris].CurrentValue = irisFStop; + this->CameraControlParameters->SetPending(vtkPlusCameraControlParameters::KEY_IRIS_FSTOP, false); + } + + + //////////////////////////// + // Exposure + if (this->CameraControlParameters->IsSet(vtkPlusCameraControlParameters::KEY_EXPOSURE_LOG2SECONDS) + && this->CameraControlParameters->IsPending(vtkPlusCameraControlParameters::KEY_EXPOSURE_LOG2SECONDS)) + { + int exposureLog2Sec = 0; + if (this->CameraControlParameters->GetExposureLog2Seconds(exposureLog2Sec) != PLUS_SUCCESS) + { + LOG_ERROR("Failed to get exposure camera control parameter"); + return PLUS_FAIL; + } + parameters.CameraControlParameters[MfVideoCapture::CaptureDeviceParameters::Exposure].CurrentValue = exposureLog2Sec; + this->CameraControlParameters->SetPending(vtkPlusCameraControlParameters::KEY_EXPOSURE_LOG2SECONDS, false); + } + + //////////////////////////// + // AutoExposure + if (this->CameraControlParameters->IsSet(vtkPlusCameraControlParameters::KEY_AUTO_EXPOSURE) + && this->CameraControlParameters->IsPending(vtkPlusCameraControlParameters::KEY_AUTO_EXPOSURE)) + { + bool autoExposure = false; + if (this->CameraControlParameters->GetAutoExposure(autoExposure) != PLUS_SUCCESS) + { + LOG_ERROR("Failed to get auto exposure camera control parameter"); + return PLUS_FAIL; + } + parameters.CameraControlParameters[MfVideoCapture::CaptureDeviceParameters::Exposure].Flag = autoExposure ? CameraControl_Flags_Auto : CameraControl_Flags_Manual; + this->CameraControlParameters->SetPending(vtkPlusCameraControlParameters::KEY_AUTO_EXPOSURE, false); + } + + //////////////////////////// + // Focus + if (this->CameraControlParameters->IsSet(vtkPlusCameraControlParameters::KEY_FOCUS_MM) + && this->CameraControlParameters->IsPending(vtkPlusCameraControlParameters::KEY_FOCUS_MM)) + { + double focusMm = 0.0; + if (this->CameraControlParameters->GetFocusMm(focusMm) != PLUS_SUCCESS) + { + LOG_ERROR("Failed to get focus camera control parameter"); + return PLUS_FAIL; + } + parameters.CameraControlParameters[MfVideoCapture::CaptureDeviceParameters::Focus].CurrentValue = focusMm; + this->CameraControlParameters->SetPending(vtkPlusCameraControlParameters::KEY_FOCUS_MM, false); + } + + //////////////////////////// + // AutoFocus + if (this->CameraControlParameters->IsSet(vtkPlusCameraControlParameters::KEY_AUTO_FOCUS) + && this->CameraControlParameters->IsPending(vtkPlusCameraControlParameters::KEY_AUTO_FOCUS)) + { + bool autoFocus = false; + if (this->CameraControlParameters->GetAutoFocus(autoFocus) != PLUS_SUCCESS) + { + LOG_ERROR("Failed to get auto focus camera control parameter"); + return PLUS_FAIL; + } + parameters.CameraControlParameters[MfVideoCapture::CaptureDeviceParameters::Focus].Flag = autoFocus ? CameraControl_Flags_Auto : CameraControl_Flags_Manual; + this->CameraControlParameters->SetPending(vtkPlusCameraControlParameters::KEY_AUTO_FOCUS, false); + } + + //////////////////////////// + // Update the parameters + MfVideoCapture::MediaFoundationVideoCaptureApi::GetInstance().SetParameters(this->ActiveVideoFormat.DeviceId, parameters); + + return PLUS_SUCCESS; } \ No newline at end of file diff --git a/src/PlusDataCollection/MicrosoftMediaFoundation/vtkPlusMmfVideoSource.h b/src/PlusDataCollection/MicrosoftMediaFoundation/vtkPlusMmfVideoSource.h index 4c3d37d63..494a51307 100644 --- a/src/PlusDataCollection/MicrosoftMediaFoundation/vtkPlusMmfVideoSource.h +++ b/src/PlusDataCollection/MicrosoftMediaFoundation/vtkPlusMmfVideoSource.h @@ -25,6 +25,7 @@ Authors include: Danielle Pace #include class MmfVideoSourceReader; +class vtkPlusCameraControlParameters; /*! \class vtkPlusMmfVideoSource @@ -96,6 +97,9 @@ class vtkPlusDataCollectionExport vtkPlusMmfVideoSource : public vtkPlusDevice std::wstring GetCaptureDeviceName(unsigned int deviceId); + /*! Set changed camera control parameter to device */ + virtual PlusStatus InternalApplyCameraControlParameterChange(); + int FrameIndex; vtkSmartPointer Mutex; @@ -103,6 +107,8 @@ class vtkPlusDataCollectionExport vtkPlusMmfVideoSource : public vtkPlusDevice VideoFormat RequestedVideoFormat; VideoFormat ActiveVideoFormat; + vtkSmartPointer CameraControlParameters; + MmfVideoSourceReader* MmfSourceReader; private: vtkPlusMmfVideoSource(const vtkPlusMmfVideoSource&); // Not implemented. diff --git a/src/PlusDataCollection/vtkPlusCameraControlParameters.cxx b/src/PlusDataCollection/vtkPlusCameraControlParameters.cxx new file mode 100644 index 000000000..adab0a298 --- /dev/null +++ b/src/PlusDataCollection/vtkPlusCameraControlParameters.cxx @@ -0,0 +1,170 @@ +/*=Plus=header=begin====================================================== +Program: Plus +Copyright (c) Laboratory for Percutaneous Surgery. All rights reserved. +See License.txt for details. +=========================================================Plus=header=end*/ + +#include "PlusConfigure.h" +#include "vtkPlusCameraControlParameters.h" + +#include + +//---------------------------------------------------------------------------- + +vtkStandardNewMacro(vtkPlusCameraControlParameters); + +//---------------------------------------------------------------------------- + +const char* vtkPlusCameraControlParameters::CAMERA_CONTROL_XML_ELEMENT_TAG = "CameraControlParameters"; +const char* vtkPlusCameraControlParameters::KEY_PAN_DEGREES = "PanDegrees"; +const char* vtkPlusCameraControlParameters::KEY_TILT_DEGREES = "TiltDegrees"; +const char* vtkPlusCameraControlParameters::KEY_ROLL_DEGREES = "RollDegrees"; +const char* vtkPlusCameraControlParameters::KEY_ZOOM_MM = "ZoomMm"; +const char* vtkPlusCameraControlParameters::KEY_IRIS_FSTOP = "IrisFStop"; +const char* vtkPlusCameraControlParameters::KEY_EXPOSURE_LOG2SECONDS = "ExposureLog2Seconds"; +const char* vtkPlusCameraControlParameters::KEY_AUTO_EXPOSURE = "AutoExposure"; +const char* vtkPlusCameraControlParameters::KEY_FOCUS_MM = "FocusMm"; +const char* vtkPlusCameraControlParameters::KEY_AUTO_FOCUS = "AutoFocus"; + +//---------------------------------------------------------------------------- +vtkPlusCameraControlParameters::vtkPlusCameraControlParameters() + : vtkPlusParameters() +{ + this->Parameters[KEY_PAN_DEGREES] = ParameterInfo("-1"); + this->Parameters[KEY_TILT_DEGREES] = ParameterInfo("-1"); + this->Parameters[KEY_ROLL_DEGREES] = ParameterInfo("-1"); + this->Parameters[KEY_ZOOM_MM] = ParameterInfo("-1"); + this->Parameters[KEY_IRIS_FSTOP] = ParameterInfo("-1"); + this->Parameters[KEY_EXPOSURE_LOG2SECONDS] = ParameterInfo("-1"); + this->Parameters[KEY_AUTO_EXPOSURE] = ParameterInfo("-1"); + this->Parameters[KEY_FOCUS_MM] = ParameterInfo("-1"); + this->Parameters[KEY_AUTO_FOCUS] = ParameterInfo("-1"); +} + +//---------------------------------------------------------------------------- +vtkPlusCameraControlParameters::~vtkPlusCameraControlParameters() +{ + LOG_TRACE("vtkPlusCameraControlParameters::~vtkPlusCameraControlParameters()"); +} + +//---------------------------------------------------------------------------- +PlusStatus vtkPlusCameraControlParameters::SetPanDegrees(double panDegrees) +{ + return this->SetValue(KEY_PAN_DEGREES, panDegrees); +} + +//---------------------------------------------------------------------------- +PlusStatus vtkPlusCameraControlParameters::GetPanDegrees(double& panDegrees) const +{ + return this->GetValue(KEY_PAN_DEGREES, panDegrees); +} + +//---------------------------------------------------------------------------- +PlusStatus vtkPlusCameraControlParameters::SetTiltDegrees(double tiltDegrees) +{ + return this->SetValue(KEY_TILT_DEGREES, tiltDegrees); +} + +//---------------------------------------------------------------------------- +PlusStatus vtkPlusCameraControlParameters::GetTiltDegrees(double& tiltDegrees) const +{ + return this->GetValue(KEY_TILT_DEGREES, tiltDegrees); +} + +//---------------------------------------------------------------------------- +PlusStatus vtkPlusCameraControlParameters::SetRollDegrees(double rollDegrees) +{ + return this->SetValue(KEY_ROLL_DEGREES, rollDegrees); +} + +//---------------------------------------------------------------------------- +PlusStatus vtkPlusCameraControlParameters::GetRollDegrees(double& rollDegrees) const +{ + return this->GetValue(KEY_ROLL_DEGREES, rollDegrees); +} + +//---------------------------------------------------------------------------- +PlusStatus vtkPlusCameraControlParameters::SetZoomMm(double zoomMm) +{ + return this->SetValue(KEY_ZOOM_MM, zoomMm); +} + +//---------------------------------------------------------------------------- +PlusStatus vtkPlusCameraControlParameters::GetZoomMm(double& zoomMm) const +{ + return this->GetValue(KEY_ZOOM_MM, zoomMm); +} + +//---------------------------------------------------------------------------- +PlusStatus vtkPlusCameraControlParameters::SetIrisFStop(int irisFStop) +{ + return this->SetValue(KEY_IRIS_FSTOP, irisFStop); +} + +//---------------------------------------------------------------------------- +PlusStatus vtkPlusCameraControlParameters::GetIrisFStop(int& irisFStop) const +{ + return this->GetValue(KEY_IRIS_FSTOP, irisFStop); +} + +//---------------------------------------------------------------------------- +PlusStatus vtkPlusCameraControlParameters::SetExposureLog2Seconds(int exposureLog2Seconds) +{ + return this->SetValue(KEY_EXPOSURE_LOG2SECONDS, exposureLog2Seconds); +} + +//---------------------------------------------------------------------------- +PlusStatus vtkPlusCameraControlParameters::GetExposureLog2Seconds(int& exposureLog2Seconds) const +{ + return this->GetValue(KEY_EXPOSURE_LOG2SECONDS, exposureLog2Seconds); +} + +//---------------------------------------------------------------------------- +PlusStatus vtkPlusCameraControlParameters::SetAutoExposure(bool autoExposure) +{ + return this->SetValue(KEY_AUTO_EXPOSURE, autoExposure ? "True" : "False"); +} + +//---------------------------------------------------------------------------- +PlusStatus vtkPlusCameraControlParameters::GetAutoExposure(bool& autoExposure) const +{ + std::string autoExposureString = ""; + if (!this->GetValue(KEY_AUTO_EXPOSURE, autoExposureString)) + { + return PLUS_FAIL; + } + + autoExposure = STRCASECMP(autoExposureString.c_str(), "true") == 0; + return PLUS_SUCCESS; +} + +//---------------------------------------------------------------------------- +PlusStatus vtkPlusCameraControlParameters::SetFocusMm(double focusMm) +{ + return this->SetValue(KEY_FOCUS_MM, focusMm); +} + +//---------------------------------------------------------------------------- +PlusStatus vtkPlusCameraControlParameters::GetFocusMm(double& focusMm) const +{ + return this->GetValue(KEY_FOCUS_MM, focusMm); +} + +//---------------------------------------------------------------------------- +PlusStatus vtkPlusCameraControlParameters::SetAutoFocus(bool autoFocus) +{ + return this->SetValue(KEY_AUTO_FOCUS, autoFocus ? "True" : "False"); +} + +//---------------------------------------------------------------------------- +PlusStatus vtkPlusCameraControlParameters::GetAutoFocus(bool& autoFocus) const +{ + std::string autoFocusString = ""; + if (!this->GetValue(KEY_AUTO_FOCUS, autoFocusString)) + { + return PLUS_FAIL; + } + + autoFocus = STRCASECMP(autoFocusString.c_str(), "true") == 0; + return PLUS_SUCCESS; +} diff --git a/src/PlusDataCollection/vtkPlusCameraControlParameters.h b/src/PlusDataCollection/vtkPlusCameraControlParameters.h new file mode 100644 index 000000000..11e89219a --- /dev/null +++ b/src/PlusDataCollection/vtkPlusCameraControlParameters.h @@ -0,0 +1,114 @@ +/*=Plus=header=begin====================================================== +Program: Plus +Copyright (c) Laboratory for Percutaneous Surgery. All rights reserved. +See License.txt for details. +=========================================================Plus=header=end*/ + +#ifndef __vtkPlusCameraControlParameters_h +#define __vtkPlusCameraControlParameters_h + +#include "vtkPlusDataCollectionExport.h" + +#include "vtkPlusParameters.h" + +#include +#include + +/*! +\class vtkPlusCameraControlParameters +\brief This class is used to store a configuration of the imaging parameters of an Microsoft Media Foundation camera device. +This class exists mainly for two reasons: +* Provide a standard interface for accessing camera parameters +* Enable standardized API for operating on camera parameters +\ingroup PlusLibDataCollection + +Currently contains the following items +* CameraControlParameters +* PanDegrees +* TiltDegrees +* RollDegrees +* ZoomMm +* IrisFStop +* ExposureLog2Seconds +* AutoExposure +* FocusMm +* AutoFocus +*/ + +class vtkPlusDataCollectionExport vtkPlusCameraControlParameters : public vtkPlusParameters +{ +public: + static const char* CAMERA_CONTROL_XML_ELEMENT_TAG; + static const char* KEY_PAN_DEGREES; + static const char* KEY_TILT_DEGREES; + static const char* KEY_ROLL_DEGREES; + static const char* KEY_ZOOM_MM; + static const char* KEY_IRIS_FSTOP; + static const char* KEY_EXPOSURE_LOG2SECONDS; + static const char* KEY_AUTO_EXPOSURE; + static const char* KEY_FOCUS_MM; + static const char* KEY_AUTO_FOCUS; + +public: + static vtkPlusCameraControlParameters* New(); + vtkTypeMacro(vtkPlusCameraControlParameters, vtkPlusParameters); + + /*! Set camera pan in degrees from -180 to +180. */ + PlusStatus SetPanDegrees(double aPanDegrees); + /*! Get camera pan in degrees from -180 to +180. */ + PlusStatus GetPanDegrees(double& aPanDegrees) const; + /*! Set camera tilt in degrees from -180 to +180. */ + PlusStatus SetTiltDegrees(double aTiltDegrees); + /*! Get camera tilt in degrees from -180 to +180. */ + PlusStatus GetTiltDegrees(double& aTiltDegrees) const; + /*! Set camera roll in degrees from -180 to +180. */ + PlusStatus SetRollDegrees(double aRollDegrees); + /*! Get camera roll in degrees from -180 to +180. */ + PlusStatus GetRollDegrees(double& aRollDegrees) const; + /*! Set camera zoom in mm. Values from 10 to 600. */ + PlusStatus SetZoomMm(double aZoomMm); + /*! Get camera zoom in mm. Values from 10 to 600. */ + PlusStatus GetZoomMm(double& aZoomMm) const; + /*! Set camera iris in f-stops. Values in units of fstop * 10. */ + PlusStatus SetIrisFStop(int aIrisFStop); + /*! Get camera iris in f-stops. Values in units of fstop * 10. */ + PlusStatus GetIrisFStop(int& aIrisFStop) const; + /*! Set camera exposure in log2 seconds. + Value Seconds + -3 1/8 + -2 1/4 + -1 1/2 + 0 1 + 1 2 + 2 4 */ + PlusStatus SetExposureLog2Seconds(int aExposureLog2Seconds); + /*! Get camera exposure in log2 seconds. + Value Seconds + -3 1/8 + -2 1/4 + -1 1/2 + 0 1 + 1 2 + 2 4 */ + PlusStatus GetExposureLog2Seconds(int& aExposureLog2Seconds) const; + /*! Set camera auto exposure enabled. */ + PlusStatus SetAutoExposure(bool aAutoExposure); + /*! Get camera auto exposure enabled. */ + PlusStatus GetAutoExposure(bool& aAutoExposure) const; + /*! Set camera focus in mm. */ + PlusStatus SetFocusMm(double aFocusMm); + /*! Get camera focus in mm. */ + PlusStatus GetFocusMm(double& aFocusMm) const; + /*! Set camera auto focus enabled. */ + PlusStatus SetAutoFocus(bool aAutoFocus); + /*! Get camera auto focus enabled. */ + PlusStatus GetAutoFocus(bool& aAutoFocus) const; + +protected: + vtkPlusCameraControlParameters(); + virtual ~vtkPlusCameraControlParameters(); + + const char* GetXMLElementName() override { return vtkPlusCameraControlParameters::CAMERA_CONTROL_XML_ELEMENT_TAG; } +}; + +#endif diff --git a/src/PlusDataCollection/vtkPlusParameters.cxx b/src/PlusDataCollection/vtkPlusParameters.cxx new file mode 100644 index 000000000..931dafef5 --- /dev/null +++ b/src/PlusDataCollection/vtkPlusParameters.cxx @@ -0,0 +1,204 @@ +/*=Plus=header=begin====================================================== +Program: Plus +Copyright (c) Laboratory for Percutaneous Surgery. All rights reserved. +See License.txt for details. +=========================================================Plus=header=end*/ + +#include "PlusConfigure.h" +#include "vtkPlusParameters.h" + +#include + +//---------------------------------------------------------------------------- +vtkStandardNewMacro(vtkPlusParameters); + +//---------------------------------------------------------------------------- + +const char* vtkPlusParameters::XML_ELEMENT_TAG = "Parameters"; +const char* vtkPlusParameters::PARAMETER_TAG = "Parameter"; +const char* vtkPlusParameters::NAME_TAG = "Name"; +const char* vtkPlusParameters::VALUE_TAG = "Value"; + +//---------------------------------------------------------------------------- +vtkPlusParameters::vtkPlusParameters() + : vtkObject() +{ +} + +//---------------------------------------------------------------------------- +vtkPlusParameters::~vtkPlusParameters() +{ + LOG_TRACE("vtkPlusParameters::~vtkPlusParameters()"); +} + +// Check +//---------------------------------------------------------------------------- +vtkPlusParameters::ParameterMapConstIterator vtkPlusParameters::begin() const +{ + return this->Parameters.begin(); +} + +//---------------------------------------------------------------------------- +vtkPlusParameters::ParameterMapConstIterator vtkPlusParameters::end() const +{ + return this->Parameters.end(); +} + +//---------------------------------------------------------------------------- +void vtkPlusParameters::PrintSelf(ostream& os, vtkIndent indent) +{ + Superclass::PrintSelf(os, indent); + + for (ParameterMap::iterator it = this->Parameters.begin(); it != this->Parameters.end(); ++it) + { + if (it->second.Set == true) + { + os << indent << it->first << ": " << it->second.Value + << (it->second.Pending ? " (pending)" : "") << std::endl; + } + } +} + +//----------------------------------------------------------------------------- +PlusStatus vtkPlusParameters::ReadConfiguration(vtkXMLDataElement* deviceConfig) +{ + vtkXMLDataElement* parameterList(NULL); + for (int i = 0; i < deviceConfig->GetNumberOfNestedElements(); ++i) + { + vtkXMLDataElement* element = deviceConfig->GetNestedElement(i); + if (STRCASECMP(element->GetName(), this->GetXMLElementName()) == 0) + { + parameterList = element; + break; + } + } + + if (parameterList == NULL) + { + LOG_ERROR("Unable to locate " << this->GetXMLElementName() << " tag in device config.Unable to read imaging parameters.Device defaults will probably be used."); + return PLUS_FAIL; + } + + for (int i = 0; i < parameterList->GetNumberOfNestedElements(); ++i) + { + vtkXMLDataElement* element = parameterList->GetNestedElement(i); + std::string name = element->GetAttribute(NAME_TAG) ? element->GetAttribute(NAME_TAG) : ""; + std::string value = element->GetAttribute(VALUE_TAG) ? element->GetAttribute(VALUE_TAG) : ""; + if (name.empty()) + { + continue; + } + + if (this->Parameters[name].Value != value) + { + // If the value changed, then mark it pending + this->Parameters[name].Pending = true; + } + this->Parameters[name].Value = value; + this->Parameters[name].Set = true; + } + + return PLUS_SUCCESS; +} + +//----------------------------------------------------------------------------- +PlusStatus vtkPlusParameters::WriteConfiguration(vtkXMLDataElement* deviceConfig) +{ + /* Create a sub node, populate it with entries of the form + + + + + + ... + + */ + + XML_FIND_NESTED_ELEMENT_CREATE_IF_MISSING(parameterList, deviceConfig, this->GetXMLElementName()); + + // Clear the list before writing new elements + parameterList->RemoveAllNestedElements(); + + for (ParameterMap::iterator it = this->Parameters.begin(); it != this->Parameters.end(); ++it) + { + if (it->second.Set == false) + { + // Don't write out parameters that are defaults + continue; + } + + vtkSmartPointer parameter = vtkSmartPointer::New(); + parameter->SetName(PARAMETER_TAG); + parameter->SetAttribute(NAME_TAG, it->first.c_str()); + parameter->SetAttribute(VALUE_TAG, it->second.Value.c_str()); + + parameterList->AddNestedElement(parameter); + } + + return PLUS_SUCCESS; +} + +//----------------------------------------------------------------------------- +bool vtkPlusParameters::IsSet(const std::string& paramName) const +{ + ParameterMapConstIterator keyIt = this->Parameters.find(paramName); + if (keyIt != this->Parameters.end()) + { + return keyIt->second.Set; + } + + LOG_ERROR("Invalid key request sent to vtkPlusParameters::IsSet -- " << paramName); + return false; +} + +//----------------------------------------------------------------------------- +bool vtkPlusParameters::IsPending(const std::string& paramName) const +{ + ParameterMapConstIterator keyIt = this->Parameters.find(paramName); + if (keyIt != this->Parameters.end()) + { + return keyIt->second.Pending; + } + + LOG_ERROR("Invalid key request sent to vtkPlusParameters::IsPending -- " << paramName); + return false; +} + +//----------------------------------------------------------------------------- +PlusStatus vtkPlusParameters::SetPending(const std::string& paramName, bool pending) +{ + ParameterMapIterator keyIt = this->Parameters.find(paramName); + if (keyIt != this->Parameters.end()) + { + if (keyIt->second.Set) + { + keyIt->second.Pending = pending; + return PLUS_SUCCESS; + } + else + { + LOG_ERROR("Pending status cannot be set for unset parameter -- " << paramName); + return PLUS_FAIL; + } + } + + LOG_ERROR("Invalid key request sent to vtkPlusParameters::SetPending -- " << paramName); + return PLUS_FAIL; +} + +//----------------------------------------------------------------------------- +PlusStatus vtkPlusParameters::DeepCopy(const vtkPlusParameters& otherParameters) +{ + for (ParameterMapConstIterator it = otherParameters.Parameters.begin(); it != otherParameters.Parameters.end(); ++it) + { + if (this->Parameters[it->first].Value != it->second.Value) + { + // If the value changed, then mark it pending + this->Parameters[it->first].Pending = true; + } + this->Parameters[it->first].Value = it->second.Value; + this->Parameters[it->first].Set = it->second.Set; + } + + return PLUS_SUCCESS; +} diff --git a/src/PlusDataCollection/vtkPlusParameters.h b/src/PlusDataCollection/vtkPlusParameters.h new file mode 100644 index 000000000..7d07f57e3 --- /dev/null +++ b/src/PlusDataCollection/vtkPlusParameters.h @@ -0,0 +1,148 @@ +/*=Plus=header=begin====================================================== +Program: Plus +Copyright (c) Laboratory for Percutaneous Surgery. All rights reserved. +See License.txt for details. +=========================================================Plus=header=end*/ + +#ifndef __vtkPlusParameters_h +#define __vtkPlusParameters_h + +#include "vtkPlusDataCollectionExport.h" + +#include +#include + +/*! +\class vtkPlusParameters +\brief This class is used as the basis to store a configuration of generic parameters for any device. +This class exists mainly for two reasons: +* Provide a standard interface for accessing parameters +* Enable standardized API for operating on parameters +\ingroup PlusLibDataCollection +*/ + +class vtkPlusDataCollectionExport vtkPlusParameters : public vtkObject +{ +protected: + class ParameterInfo + { + public: + ParameterInfo() : Value(""), Set(false), Pending(false) {}; + ParameterInfo(std::string defaultValue) : Value(defaultValue), Set(false), Pending(false) {}; + + /// Serialized parameter value + std::string Value; + /// Flag indicating whether the invalid default has been changed to meaningful value + /// (Note: sound velocity has a meaningful default) + bool Set; + /// Flag indicating whether the parameter is changed but has not been set to device + bool Pending; + }; + typedef std::map ParameterMap; + typedef ParameterMap::iterator ParameterMapIterator; + typedef ParameterMap::const_iterator ParameterMapConstIterator; + + /*! Return an iterator to the beginning of the parameter space */ + ParameterMapConstIterator begin() const; + /*! Return an iterator to the end of the parameter space */ + ParameterMapConstIterator end() const; + + public: + static const char* XML_ELEMENT_TAG; + static const char* PARAMETER_TAG; + static const char* NAME_TAG; + static const char* VALUE_TAG; + +public: + static vtkPlusParameters* New(); + vtkTypeMacro(vtkPlusParameters, vtkObject); + + /*! + Read main configuration from/to XML data + Assumes that the data element passed is the device element, not the root! + \param deviceConfig the XML element of the device + */ + virtual PlusStatus ReadConfiguration(vtkXMLDataElement* deviceConfig); + + /*! + Write main configuration from/to XML data + Assumes that the data element passed is the device element, not the root! + \param deviceConfig the XML element of the device + */ + virtual PlusStatus WriteConfiguration(vtkXMLDataElement* deviceConfig); + + /*! + Copy the values from another imaging parameters + */ + virtual PlusStatus DeepCopy(const vtkPlusParameters& otherParameters); + + /*! + Request a stored value by key name + \param paramName the key value to retrieve + \param outputValue the output variable to write to + */ + template PlusStatus GetValue(const std::string& paramName, T& outputValue) const + { + ParameterMapConstIterator keyIt = this->Parameters.find(paramName); + if (keyIt != this->Parameters.end() && keyIt->second.Set == false) + { + return PLUS_FAIL; + } + else if (keyIt == this->Parameters.end()) + { + return PLUS_FAIL; + } + + std::stringstream ss; + ParameterMapConstIterator it = this->Parameters.find(paramName); + ss.str(it->second.Value); + ss >> outputValue; + return PLUS_SUCCESS; + } + + /*! + Set a stored value by key name + Defined in the header to make it available externally + \param paramName the key value to retrieve + \param aValue the value to write + */ + template PlusStatus SetValue(const std::string& paramName, T aValue) + { + std::stringstream ss; + ss << aValue; + if (this->Parameters[paramName].Value != ss.str()) + { + this->Parameters[paramName].Pending = true; + } + this->Parameters[paramName].Value = ss.str(); + this->Parameters[paramName].Set = true; + return PLUS_SUCCESS; + }; + /*! + Request the set status of a parameter (whether it is not the default value) + \param paramName the key value to retrieve + */ + bool IsSet(const std::string& paramName) const; + /*! + Request the pending status of a parameter + \param paramName the key value to retrieve + */ + bool IsPending(const std::string& paramName) const; + /*! + Set the pending status of a parameter + */ + PlusStatus SetPending(const std::string& paramName, bool pending); + + /*! Print the list of supported parameters. For diagnostic purposes only. */ + virtual void PrintSelf(ostream& os, vtkIndent indent) VTK_OVERRIDE; + +protected: + vtkPlusParameters(); + virtual ~vtkPlusParameters(); + + virtual const char* GetXMLElementName() { return vtkPlusParameters::XML_ELEMENT_TAG; }; + + ParameterMap Parameters; +}; + +#endif \ No newline at end of file diff --git a/src/PlusDataCollection/vtkPlusUsImagingParameters.cxx b/src/PlusDataCollection/vtkPlusUsImagingParameters.cxx index 3d137c833..c0447b809 100644 --- a/src/PlusDataCollection/vtkPlusUsImagingParameters.cxx +++ b/src/PlusDataCollection/vtkPlusUsImagingParameters.cxx @@ -15,10 +15,7 @@ vtkStandardNewMacro(vtkPlusUsImagingParameters); //---------------------------------------------------------------------------- -const char* vtkPlusUsImagingParameters::XML_ELEMENT_TAG = "UsImagingParameters"; -const char* vtkPlusUsImagingParameters::US_PARAMETER_TAG = "UsParameter"; -const char* vtkPlusUsImagingParameters::NAME_TAG = "name"; -const char* vtkPlusUsImagingParameters::VALUE_TAG = "value"; +const char* vtkPlusUsImagingParameters::US_XML_ELEMENT_TAG = "UsImagingParameters"; const char* vtkPlusUsImagingParameters::KEY_CONTRAST = "Contrast"; const char* vtkPlusUsImagingParameters::KEY_DEPTH = "DepthMm"; const char* vtkPlusUsImagingParameters::KEY_FOCUS_DEPTH = "FocusDepthPercent"; @@ -36,7 +33,7 @@ const char* vtkPlusUsImagingParameters::KEY_IMAGESIZE = "ImageSize"; //---------------------------------------------------------------------------- vtkPlusUsImagingParameters::vtkPlusUsImagingParameters() - : vtkObject() + : vtkPlusParameters() { this->Parameters[KEY_FREQUENCY] = ParameterInfo("-1"); this->Parameters[KEY_DEPTH] = ParameterInfo("-1"); @@ -332,19 +329,6 @@ float vtkPlusUsImagingParameters::GetSoundVelocity() const return aValue; } -// Check -//---------------------------------------------------------------------------- -vtkPlusUsImagingParameters::ParameterMapConstIterator vtkPlusUsImagingParameters::begin() const -{ - return this->Parameters.begin(); -} - -//---------------------------------------------------------------------------- -vtkPlusUsImagingParameters::ParameterMapConstIterator vtkPlusUsImagingParameters::end() const -{ - return this->Parameters.end(); -} - //---------------------------------------------------------------------------- PlusStatus vtkPlusUsImagingParameters::SetProbeVoltage(float aVoltage) { @@ -430,162 +414,3 @@ FrameSizeType vtkPlusUsImagingParameters::GetImageSize() const this->GetImageSize(imageSize); return imageSize; } - -//---------------------------------------------------------------------------- -void vtkPlusUsImagingParameters::PrintSelf(ostream& os, vtkIndent indent) -{ - Superclass::PrintSelf(os, indent); - - for (ParameterMap::iterator it = this->Parameters.begin(); it != this->Parameters.end(); ++it) - { - if (it->second.Set == true) - { - os << indent << it->first << ": " << it->second.Value - << (it->second.Pending ? " (pending)" : "") << std::endl; - } - } -} - -//----------------------------------------------------------------------------- -PlusStatus vtkPlusUsImagingParameters::ReadConfiguration(vtkXMLDataElement* deviceConfig) -{ - vtkXMLDataElement* parameterList(NULL); - for (int i = 0; i < deviceConfig->GetNumberOfNestedElements(); ++i) - { - vtkXMLDataElement* element = deviceConfig->GetNestedElement(i); - if (STRCASECMP(element->GetName(), XML_ELEMENT_TAG) == 0) - { - parameterList = element; - break; - } - } - - if (parameterList == NULL) - { - LOG_ERROR("Unable to locate UsImagingParameters tag in device config. Unable to read imaging parameters. Device defaults will probably be used."); - return PLUS_FAIL; - } - - for (int i = 0; i < parameterList->GetNumberOfNestedElements(); ++i) - { - vtkXMLDataElement* element = parameterList->GetNestedElement(i); - std::string name = element->GetAttribute(NAME_TAG) ? element->GetAttribute(NAME_TAG) : ""; - std::string value = element->GetAttribute(VALUE_TAG) ? element->GetAttribute(VALUE_TAG) : ""; - if (name.empty()) - { - continue; - } - - if (this->Parameters[name].Value != value) - { - // If the value changed, then mark it pending - this->Parameters[name].Pending = true; - } - this->Parameters[name].Value = value; - this->Parameters[name].Set = true; - } - - return PLUS_SUCCESS; -} - -//----------------------------------------------------------------------------- -PlusStatus vtkPlusUsImagingParameters::WriteConfiguration(vtkXMLDataElement* deviceConfig) -{ - /* Create a sub node, populate it with entries of the form - - - - - - ... - - */ - - XML_FIND_NESTED_ELEMENT_CREATE_IF_MISSING(parameterList, deviceConfig, XML_ELEMENT_TAG); - - // Clear the list before writing new elements - parameterList->RemoveAllNestedElements(); - - for (ParameterMap::iterator it = this->Parameters.begin(); it != this->Parameters.end(); ++it) - { - if (it->second.Set == false) - { - // Don't write out parameters that are defaults - continue; - } - - vtkSmartPointer parameter = vtkSmartPointer::New(); - parameter->SetName(US_PARAMETER_TAG); - parameter->SetAttribute(NAME_TAG, it->first.c_str()); - parameter->SetAttribute(VALUE_TAG, it->second.Value.c_str()); - - parameterList->AddNestedElement(parameter); - } - - return PLUS_SUCCESS; -} - -//----------------------------------------------------------------------------- -bool vtkPlusUsImagingParameters::IsSet(const std::string& paramName) const -{ - ParameterMapConstIterator keyIt = this->Parameters.find(paramName); - if (keyIt != this->Parameters.end()) - { - return keyIt->second.Set; - } - - LOG_ERROR("Invalid key request sent to vtkPlusUsImagingParameters::IsSet -- " << paramName); - return false; -} - -//----------------------------------------------------------------------------- -bool vtkPlusUsImagingParameters::IsPending(const std::string& paramName) const -{ - ParameterMapConstIterator keyIt = this->Parameters.find(paramName); - if (keyIt != this->Parameters.end()) - { - return keyIt->second.Pending; - } - - LOG_ERROR("Invalid key request sent to vtkPlusUsImagingParameters::IsPending -- " << paramName); - return false; -} - -//----------------------------------------------------------------------------- -PlusStatus vtkPlusUsImagingParameters::SetPending(const std::string& paramName, bool pending) -{ - ParameterMapIterator keyIt = this->Parameters.find(paramName); - if (keyIt != this->Parameters.end()) - { - if (keyIt->second.Set) - { - keyIt->second.Pending = pending; - return PLUS_SUCCESS; - } - else - { - LOG_ERROR("Pending status cannot be set for unset parameter -- " << paramName); - return PLUS_FAIL; - } - } - - LOG_ERROR("Invalid key request sent to vtkPlusUsImagingParameters::SetPending -- " << paramName); - return PLUS_FAIL; -} - -//----------------------------------------------------------------------------- -PlusStatus vtkPlusUsImagingParameters::DeepCopy(const vtkPlusUsImagingParameters& otherParameters) -{ - for (ParameterMapConstIterator it = otherParameters.Parameters.begin(); it != otherParameters.Parameters.end(); ++it) - { - if (this->Parameters[it->first].Value != it->second.Value) - { - // If the value changed, then mark it pending - this->Parameters[it->first].Pending = true; - } - this->Parameters[it->first].Value = it->second.Value; - this->Parameters[it->first].Set = it->second.Set; - } - - return PLUS_SUCCESS; -} diff --git a/src/PlusDataCollection/vtkPlusUsImagingParameters.h b/src/PlusDataCollection/vtkPlusUsImagingParameters.h index 642fa65ac..8e82c9336 100644 --- a/src/PlusDataCollection/vtkPlusUsImagingParameters.h +++ b/src/PlusDataCollection/vtkPlusUsImagingParameters.h @@ -9,6 +9,8 @@ See License.txt for details. #include "vtkPlusDataCollectionExport.h" +#include "vtkPlusParameters.h" + #include #include @@ -38,37 +40,10 @@ Currently contains the following items * SoundVelocity */ -class vtkPlusDataCollectionExport vtkPlusUsImagingParameters : public vtkObject +class vtkPlusDataCollectionExport vtkPlusUsImagingParameters : public vtkPlusParameters { -protected: - class ParameterInfo - { - public: - ParameterInfo() : Value(""), Set(false), Pending(false) {}; - ParameterInfo(std::string defaultValue) : Value(defaultValue), Set(false), Pending(false) {}; - - /// Serialized parameter value - std::string Value; - /// Flag indicating whether the invalid default has been changed to meaningful value - /// (Note: sound velocity has a meaningful default) - bool Set; - /// Flag indicating whether the parameter is changed but has not been set to device - bool Pending; - }; - typedef std::map ParameterMap; - typedef ParameterMap::iterator ParameterMapIterator; - typedef ParameterMap::const_iterator ParameterMapConstIterator; - - /*! Return an iterator to the beginning of the parameter space */ - ParameterMapConstIterator begin() const; - /*! Return an iterator to the end of the parameter space */ - ParameterMapConstIterator end() const; - public: - static const char* XML_ELEMENT_TAG; - static const char* US_PARAMETER_TAG; - static const char* NAME_TAG; - static const char* VALUE_TAG; + static const char* US_XML_ELEMENT_TAG; static const char* KEY_FREQUENCY; static const char* KEY_DEPTH; static const char* KEY_FOCUS_DEPTH; @@ -86,83 +61,7 @@ class vtkPlusDataCollectionExport vtkPlusUsImagingParameters : public vtkObject public: static vtkPlusUsImagingParameters* New(); - vtkTypeMacro(vtkPlusUsImagingParameters, vtkObject); - - /*! - Read main configuration from/to XML data - Assumes that the data element passed is the device element, not the root! - \param deviceConfig the XML element of the device - */ - virtual PlusStatus ReadConfiguration(vtkXMLDataElement* deviceConfig); - - /*! - Write main configuration from/to XML data - Assumes that the data element passed is the device element, not the root! - \param deviceConfig the XML element of the device - */ - virtual PlusStatus WriteConfiguration(vtkXMLDataElement* deviceConfig); - - /*! - Copy the values from another imaging parameters - */ - virtual PlusStatus DeepCopy(const vtkPlusUsImagingParameters& otherParameters); - - /*! - Request a stored value by key name - \param paramName the key value to retrieve - \param outputValue the output variable to write to - */ - template PlusStatus GetValue(const std::string& paramName, T& outputValue) const - { - ParameterMapConstIterator keyIt = this->Parameters.find(paramName); - if (keyIt != this->Parameters.end() && keyIt->second.Set == false) - { - return PLUS_FAIL; - } - else if (keyIt == this->Parameters.end()) - { - return PLUS_FAIL; - } - - std::stringstream ss; - ParameterMapConstIterator it = this->Parameters.find(paramName); - ss.str(it->second.Value); - ss >> outputValue; - return PLUS_SUCCESS; - } - - /*! - Set a stored value by key name - Defined in the header to make it available externally - \param paramName the key value to retrieve - \param aValue the value to write - */ - template PlusStatus SetValue(const std::string& paramName, T aValue) - { - std::stringstream ss; - ss << aValue; - if (this->Parameters[paramName].Value != ss.str()) - { - this->Parameters[paramName].Pending = true; - } - this->Parameters[paramName].Value = ss.str(); - this->Parameters[paramName].Set = true; - return PLUS_SUCCESS; - }; - /*! - Request the set status of a parameter (whether it is not the default value) - \param paramName the key value to retrieve - */ - bool IsSet(const std::string& paramName) const; - /*! - Request the pending status of a parameter - \param paramName the key value to retrieve - */ - bool IsPending(const std::string& paramName) const; - /*! - Set the pending status of a parameter - */ - PlusStatus SetPending(const std::string& paramName, bool pending); + vtkTypeMacro(vtkPlusUsImagingParameters, vtkPlusParameters); /*! Set ultrasound transmitter frequency (MHz) */ PlusStatus SetFrequencyMhz(double aFrequencyMhz); @@ -250,9 +149,6 @@ class vtkPlusDataCollectionExport vtkPlusUsImagingParameters : public vtkObject PlusStatus GetImageSize(FrameSizeType& imageSize) const; FrameSizeType GetImageSize() const; - /*! Print the list of supported parameters. For diagnostic purposes only. */ - virtual void PrintSelf(ostream& os, vtkIndent indent) VTK_OVERRIDE; - enum ImagingMode { BMode = 0, @@ -319,6 +215,8 @@ class vtkPlusDataCollectionExport vtkPlusUsImagingParameters : public vtkObject vtkPlusUsImagingParameters(); virtual ~vtkPlusUsImagingParameters(); + const char* GetXMLElementName() override { return vtkPlusUsImagingParameters::US_XML_ELEMENT_TAG; } + ParameterMap Parameters; };