PlusLib  2.9.0
Software library for tracked ultrasound image acquisition, calibration, and processing.
vtkPlusReconstructVolumeCommand.cxx
Go to the documentation of this file.
1 /*=Plus=header=begin======================================================
2 Program: Plus
3 Copyright (c) Laboratory for Percutaneous Surgery. All rights reserved.
4 See License.txt for details.
5 =========================================================Plus=header=end*/
6 
7 #include "PlusConfigure.h"
8 #include "vtkPlusDataCollector.h"
9 #include "vtkImageData.h"
10 #include "vtkObjectFactory.h"
11 #include "vtkPlusChannel.h"
14 #include "vtkIGSIOTrackedFrameList.h"
15 #include "vtkIGSIOTransformRepository.h"
18 #include <limits>
19 
20 namespace
21 {
22  static const double UNDEFINED_VALUE = std::numeric_limits<double>::max();
23  static const std::string RECONSTRUCT_PRERECORDED_CMD = "ReconstructVolume";
24  static const std::string START_LIVE_RECONSTRUCTION_CMD = "StartVolumeReconstruction";
25  static const std::string SUSPEND_LIVE_RECONSTRUCTION_CMD = "SuspendVolumeReconstruction";
26  static const std::string RESUME_LIVE_RECONSTRUCTION_CMD = "ResumeVolumeReconstruction";
27  static const std::string STOP_LIVE_RECONSTRUCTION_CMD = "StopVolumeReconstruction";
28  static const std::string GET_LIVE_RECONSTRUCTION_SNAPSHOT_CMD = "GetVolumeReconstructionSnapshot";
29 }
30 
32 
33 //----------------------------------------------------------------------------
35  : ApplyHoleFilling(true)
36 {
37  this->OutputOrigin[0] = UNDEFINED_VALUE;
38  this->OutputOrigin[1] = UNDEFINED_VALUE;
39  this->OutputOrigin[2] = UNDEFINED_VALUE;
40  this->OutputSpacing[0] = UNDEFINED_VALUE;
41  this->OutputSpacing[1] = UNDEFINED_VALUE;
42  this->OutputSpacing[2] = UNDEFINED_VALUE;
43  this->OutputExtent[0] = 0;
44  this->OutputExtent[1] = -1;
45  this->OutputExtent[2] = 0;
46  this->OutputExtent[3] = -1;
47  this->OutputExtent[4] = 0;
48  this->OutputExtent[5] = -1;
49 }
50 
51 //----------------------------------------------------------------------------
53 {
54 }
55 
56 //----------------------------------------------------------------------------
58 {
59  SetName(RECONSTRUCT_PRERECORDED_CMD);
60 }
62 {
63  SetName(START_LIVE_RECONSTRUCTION_CMD);
64 }
66 {
67  SetName(STOP_LIVE_RECONSTRUCTION_CMD);
68 }
70 {
71  SetName(SUSPEND_LIVE_RECONSTRUCTION_CMD);
72 }
74 {
75  SetName(RESUME_LIVE_RECONSTRUCTION_CMD);
76 }
78 {
79  SetName(GET_LIVE_RECONSTRUCTION_SNAPSHOT_CMD);
80 }
81 
82 //----------------------------------------------------------------------------
83 void vtkPlusReconstructVolumeCommand::PrintSelf(ostream& os, vtkIndent indent)
84 {
85  this->Superclass::PrintSelf(os, indent);
86 }
87 
88 //----------------------------------------------------------------------------
89 void vtkPlusReconstructVolumeCommand::GetCommandNames(std::list<std::string>& cmdNames)
90 {
91  cmdNames.clear();
92  cmdNames.push_back(RECONSTRUCT_PRERECORDED_CMD);
93  cmdNames.push_back(START_LIVE_RECONSTRUCTION_CMD);
94  cmdNames.push_back(SUSPEND_LIVE_RECONSTRUCTION_CMD);
95  cmdNames.push_back(RESUME_LIVE_RECONSTRUCTION_CMD);
96  cmdNames.push_back(STOP_LIVE_RECONSTRUCTION_CMD);
97  cmdNames.push_back(GET_LIVE_RECONSTRUCTION_SNAPSHOT_CMD);
98 }
99 
100 //----------------------------------------------------------------------------
101 std::string vtkPlusReconstructVolumeCommand::GetDescription(const std::string& commandName)
102 {
103  std::string desc;
104  if (commandName.empty() || igsioCommon::IsEqualInsensitive(commandName, RECONSTRUCT_PRERECORDED_CMD))
105  {
106  desc += RECONSTRUCT_PRERECORDED_CMD;
107  desc += ": Reconstruct a volume from a file and writes the result to a file. Attributes: InputSeqFilename: name of the input sequence file name that contains the list of frames. OutputVolFilename: name of the output volume file name (optional). OutputVolDeviceName: name of the OpenIGTLink device for the IMAGE message (optional).";
108  }
109  if (commandName.empty() || igsioCommon::IsEqualInsensitive(commandName, START_LIVE_RECONSTRUCTION_CMD))
110  {
111  desc += START_LIVE_RECONSTRUCTION_CMD;
112  desc += ": Start adding acquired frames to the volume. Attributes: VolumeReconstructorDeviceId: ID of the volume reconstructor device. OutputVolFilename: name of the output volume file name (optional). OutputVolDeviceName: name of the OpenIGTLink device for the IMAGE message (optional).";
113  }
114  if (commandName.empty() || igsioCommon::IsEqualInsensitive(commandName, SUSPEND_LIVE_RECONSTRUCTION_CMD))
115  {
116  desc += SUSPEND_LIVE_RECONSTRUCTION_CMD;
117  desc += ": Suspend adding acquired frames to the volume. Attributes: VolumeReconstructorDeviceId: ID of the volume reconstructor device.";
118  }
119  if (commandName.empty() || igsioCommon::IsEqualInsensitive(commandName, RESUME_LIVE_RECONSTRUCTION_CMD))
120  {
121  desc += RESUME_LIVE_RECONSTRUCTION_CMD;
122  desc += ": Resume adding acquired frames to the volume. Attributes: VolumeReconstructorDeviceId: ID of the volume reconstructor device.";
123  }
124  if (commandName.empty() || igsioCommon::IsEqualInsensitive(commandName, STOP_LIVE_RECONSTRUCTION_CMD))
125  {
126  desc += STOP_LIVE_RECONSTRUCTION_CMD;
127  desc += ": Stop adding acquired frames to the volume, finalize reconstruction, and save/send the results. Attributes: VolumeReconstructorDeviceId: ID of the volume reconstructor device. OutputVolFilename: name of the output volume file name (optional). OutputVolDeviceName: name of the OpenIGTLink device for the IMAGE message (optional).";
128  }
129  if (commandName.empty() || igsioCommon::IsEqualInsensitive(commandName, GET_LIVE_RECONSTRUCTION_SNAPSHOT_CMD))
130  {
131  desc += GET_LIVE_RECONSTRUCTION_SNAPSHOT_CMD;
132  desc += ": Request a snapshot of the live reconstruction result. Attributes: VolumeReconstructorDeviceId: ID of the volume reconstructor device. OutputVolFilename: name of the output volume file name (optional). OutputVolDeviceName: name of the OpenIGTLink device for the IMAGE message (optional). ApplyHoleFilling: if FALSE then holes will not be filled (optional, default: TRUE).";
133  }
134 
135  return desc;
136 }
137 
138 //----------------------------------------------------------------------------
140 {
142  {
143  return PLUS_FAIL;
144  }
145  XML_READ_STRING_ATTRIBUTE_OPTIONAL(InputSeqFilename, aConfig);
146  XML_READ_STRING_ATTRIBUTE_OPTIONAL(OutputVolFilename, aConfig);
147  XML_READ_STRING_ATTRIBUTE_OPTIONAL(OutputVolDeviceName, aConfig);
148  this->SetVolumeReconstructorDeviceId(aConfig->GetAttribute("VolumeReconstructorDeviceId"));
149 
150  // output volume parameters
151  // origin and spacing is defined in the reference coordinate system
152  XML_READ_VECTOR_ATTRIBUTE_OPTIONAL(double, 3, OutputSpacing, aConfig);
153  XML_READ_VECTOR_ATTRIBUTE_OPTIONAL(double, 3, OutputOrigin, aConfig);
154  XML_READ_VECTOR_ATTRIBUTE_OPTIONAL(int, 6, OutputExtent, aConfig);
155 
156  XML_READ_BOOL_ATTRIBUTE_OPTIONAL(ApplyHoleFilling, aConfig);
157  return PLUS_SUCCESS;
158 }
159 
160 //----------------------------------------------------------------------------
162 {
164  {
165  return PLUS_FAIL;
166  }
167 
168  XML_WRITE_STRING_ATTRIBUTE_IF_NOT_EMPTY(VolumeReconstructorDeviceId, aConfig);
169  XML_WRITE_STRING_ATTRIBUTE_IF_NOT_EMPTY(InputSeqFilename, aConfig);
170  XML_WRITE_STRING_ATTRIBUTE_IF_NOT_EMPTY(OutputVolFilename, aConfig);
171  XML_WRITE_STRING_ATTRIBUTE_IF_NOT_EMPTY(OutputVolDeviceName, aConfig);
172 
173  if (this->OutputOrigin[0] != UNDEFINED_VALUE
174  && this->OutputOrigin[1] != UNDEFINED_VALUE
175  && this->OutputOrigin[2] != UNDEFINED_VALUE)
176  {
177  aConfig->SetVectorAttribute("OutputOrigin", 3, this->OutputOrigin);
178  }
179 
180  if (this->OutputSpacing[0] != UNDEFINED_VALUE
181  && this->OutputSpacing[1] != UNDEFINED_VALUE
182  && this->OutputSpacing[2] != UNDEFINED_VALUE)
183  {
184  aConfig->SetVectorAttribute("OutputSpacing", 3, this->OutputSpacing);
185  }
186 
187  if (this->OutputExtent[1] >= this->OutputExtent[0]
188  && this->OutputExtent[3] >= this->OutputExtent[2]
189  && this->OutputExtent[5] >= this->OutputExtent[4])
190  {
191  aConfig->SetVectorAttribute("OutputExtent", 6, this->OutputExtent);
192  }
193 
194  XML_WRITE_BOOL_ATTRIBUTE(ApplyHoleFilling, aConfig);
195 
196  return PLUS_SUCCESS;
197 }
198 
199 //----------------------------------------------------------------------------
201 {
202  LOG_DEBUG("vtkPlusReconstructVolumeCommand::Execute: " << (!this->Name.empty() ? this->Name : "(undefined)")
203  << ", device: " << (this->VolumeReconstructorDeviceId.empty() ? "(undefined)" : this->VolumeReconstructorDeviceId));
204 
205  if (this->Name.empty())
206  {
207  this->QueueCommandResponse(PLUS_FAIL, "Command failed. See error message.", "No command name specified.");
208  return PLUS_FAIL;
209  }
210 
212  if (reconstructorDevice == NULL)
213  {
214  this->QueueCommandResponse(PLUS_FAIL, "Command failed. See error message.", std::string("Device ")
215  + (this->VolumeReconstructorDeviceId.empty() ? "(undefined)" : this->VolumeReconstructorDeviceId) + std::string(" is not found."));
216  return PLUS_FAIL;
217  }
218 
219  // If output volume filename and/or device name is specified then update it in the reconstructor device
220  if (!this->GetOutputVolFilename().empty())
221  {
222  reconstructorDevice->SetOutputVolFilename(this->GetOutputVolFilename());
223  }
224  if (!this->GetOutputVolDeviceName().empty())
225  {
226  reconstructorDevice->SetOutputVolDeviceName(this->GetOutputVolDeviceName());
227  }
228  std::string outputVolFilename = (!reconstructorDevice->GetOutputVolFilename().empty() ? reconstructorDevice->GetOutputVolFilename() : "");
229  std::string outputVolDeviceName = (!reconstructorDevice->GetOutputVolDeviceName().empty() ? reconstructorDevice->GetOutputVolDeviceName() : "");
230 
231  std::string reconstructorDeviceId = (reconstructorDevice->GetDeviceId().empty() ? "(unknown)" : reconstructorDevice->GetDeviceId());
232 
233  // Set output volume size and resolution
234  if (igsioCommon::IsEqualInsensitive(this->Name, RECONSTRUCT_PRERECORDED_CMD) || igsioCommon::IsEqualInsensitive(this->Name, START_LIVE_RECONSTRUCTION_CMD))
235  {
236  // Only allow changing the output volume when we start the reconstruction
237  if (this->OutputOrigin[0] != UNDEFINED_VALUE && this->OutputOrigin[1] != UNDEFINED_VALUE && this->OutputOrigin[2] != UNDEFINED_VALUE)
238  {
239  reconstructorDevice->SetOutputOrigin(this->OutputOrigin);
240  }
241 
242  if (this->OutputSpacing[0] != UNDEFINED_VALUE && this->OutputSpacing[1] != UNDEFINED_VALUE && this->OutputSpacing[2] != UNDEFINED_VALUE)
243  {
244  reconstructorDevice->SetOutputSpacing(this->OutputSpacing);
245  }
246 
247  if (this->OutputExtent[1] >= this->OutputExtent[0] && this->OutputExtent[3] >= this->OutputExtent[2] && this->OutputExtent[5] >= this->OutputExtent[4])
248  {
249  reconstructorDevice->SetOutputExtent(this->OutputExtent);
250  }
251  }
252 
253  std::string baseMessage = this->Name + std::string("(") + reconstructorDeviceId + std::string(")");
254  if (igsioCommon::IsEqualInsensitive(this->Name, RECONSTRUCT_PRERECORDED_CMD))
255  {
256  LOG_INFO("Volume reconstruction from sequence file: " << (!this->InputSeqFilename.empty() ? this->InputSeqFilename : "(undefined)") << ", device: " << reconstructorDeviceId);
257  if (reconstructorDevice->GetEnableReconstruction())
258  {
259  this->QueueCommandResponse(PLUS_FAIL, "Command failed. See error message.", baseMessage + " Reconstruction from sequence file failed: live volume reconstruction is in progress.");
260  return PLUS_FAIL;
261  }
262  if (reconstructorDevice->UpdateTransformRepository(this->CommandProcessor->GetPlusServer()->GetTransformRepository()) != PLUS_SUCCESS)
263  {
264  this->QueueCommandResponse(PLUS_FAIL, "Command failed. See error message.", baseMessage + " Reconstruction from sequence file failed: cannot get transform repository.");
265  return PLUS_FAIL;
266  }
267  reconstructorDevice->Reset(); // Clear volume
268  vtkSmartPointer<vtkImageData> volumeToSend = vtkSmartPointer<vtkImageData>::New();
269  std::string errorMessage;
270  if (reconstructorDevice->GetReconstructedVolumeFromFile(this->InputSeqFilename, volumeToSend, errorMessage) != PLUS_SUCCESS)
271  {
272  this->QueueCommandResponse(PLUS_FAIL, "Command failed. See error message.", baseMessage + " Reconstruction from sequence file failed: " + errorMessage);
273  return PLUS_FAIL;
274  }
275  std::string statusMessage;
276  PlusStatus status = ProcessImageReply(volumeToSend, outputVolFilename, outputVolDeviceName, statusMessage);
277  this->QueueCommandResponse(status, std::string("Command ") + std::string((status == PLUS_SUCCESS ? "succeeded." : "failed. See error message.")), baseMessage + " Reconstruction from sequence file completed: " + statusMessage);
278  return status;
279  }
280  else if (igsioCommon::IsEqualInsensitive(this->Name, START_LIVE_RECONSTRUCTION_CMD))
281  {
282  LOG_INFO("Volume reconstruction from live frames starting, device: " << reconstructorDeviceId);
283  if (reconstructorDevice->GetEnableReconstruction())
284  {
285  this->QueueCommandResponse(PLUS_FAIL, "Command failed. See error message.", baseMessage + " Reconstruction starting from live frames failed: live volume reconstruction is in progress.");
286  return PLUS_FAIL;
287  }
288  if (reconstructorDevice->UpdateTransformRepository(this->CommandProcessor->GetPlusServer()->GetTransformRepository()) != PLUS_SUCCESS)
289  {
290  this->QueueCommandResponse(PLUS_FAIL, "Command failed. See error message.", baseMessage + " Reconstruction starting from live frames failed: cannot get transform repository.");
291  return PLUS_FAIL;
292  }
293  reconstructorDevice->Reset(); // Clear volume
294  reconstructorDevice->SetEnableReconstruction(true);
295  this->QueueCommandResponse(PLUS_SUCCESS, baseMessage + " Volume reconstruction from live frames started.");
296  return PLUS_SUCCESS;
297  }
298  else if (igsioCommon::IsEqualInsensitive(this->Name, STOP_LIVE_RECONSTRUCTION_CMD))
299  {
300  // it's stopped if: not in progress (it may be just suspended) and no frames have been recorded
301  if (!reconstructorDevice->GetEnableReconstruction() && reconstructorDevice->GetTotalFramesRecorded() == 0)
302  {
303  this->QueueCommandResponse(PLUS_FAIL, "Command failed. See error message.", baseMessage + " Reconstruction stop from live frames failed: live volume reconstruction is already stopped, device.");
304  return PLUS_FAIL;
305  }
306 
307  LOG_INFO("Volume reconstruction from live frames stopping, device: " << reconstructorDeviceId);
308  reconstructorDevice->SetEnableReconstruction(false);
309  vtkSmartPointer<vtkImageData> volumeToSend = vtkSmartPointer<vtkImageData>::New();
310  std::string errorMessage;
311  if (reconstructorDevice->GetReconstructedVolume(volumeToSend, errorMessage) != PLUS_SUCCESS)
312  {
313  this->QueueCommandResponse(PLUS_FAIL, "Command failed. See error message.", baseMessage + "Reconstruction stop from live frames failed: " + errorMessage);
314  return PLUS_FAIL;
315  }
316  reconstructorDevice->Reset(); // Clear volume
317  std::string statusMessage;
318  PlusStatus status = ProcessImageReply(volumeToSend, outputVolFilename, outputVolDeviceName, statusMessage);
319  this->QueueCommandResponse(status, std::string("Command ") + std::string((status == PLUS_SUCCESS ? "succeeded." : "failed. See error message.")), baseMessage + " Reconstruction from live frames completed: " + statusMessage);
320  return status;
321  }
322  else if (igsioCommon::IsEqualInsensitive(this->Name, GET_LIVE_RECONSTRUCTION_SNAPSHOT_CMD))
323  {
324  LOG_INFO("Volume reconstruction from live frames snapshot request, device: " << reconstructorDeviceId);
325  vtkSmartPointer<vtkImageData> volumeToSend = vtkSmartPointer<vtkImageData>::New();
326  std::string errorMessage;
327  if (reconstructorDevice->GetReconstructedVolume(volumeToSend, errorMessage, this->ApplyHoleFilling) != PLUS_SUCCESS)
328  {
329  this->QueueCommandResponse(PLUS_FAIL, "Command failed. See error message.", baseMessage + " Reconstruction snapshot request failed, device: " + errorMessage);
330  return PLUS_FAIL;
331  }
332  std::string statusMessage;
333  PlusStatus status = ProcessImageReply(volumeToSend, outputVolFilename, outputVolDeviceName, statusMessage);
334  this->QueueCommandResponse(status, std::string("Command ") + std::string((status == PLUS_SUCCESS ? "succeeded." : "failed. See error message.")), baseMessage + " " + statusMessage);
335  return status;
336  }
337  else if (igsioCommon::IsEqualInsensitive(this->Name, SUSPEND_LIVE_RECONSTRUCTION_CMD))
338  {
339  LOG_INFO("Volume reconstruction from live frames suspending, device: " << reconstructorDeviceId);
340  if (!reconstructorDevice->GetEnableReconstruction())
341  {
342  this->QueueCommandResponse(PLUS_FAIL, "Command failed. See error message.", baseMessage + " Reconstruction suspend from live frames failed: live volume reconstruction is not in progress.");
343  return PLUS_FAIL;
344  }
345  reconstructorDevice->SetEnableReconstruction(false);
346  this->QueueCommandResponse(PLUS_SUCCESS, "Volume reconstruction from live frames suspended, device: " + reconstructorDeviceId);
347  return PLUS_SUCCESS;
348  }
349  else if (igsioCommon::IsEqualInsensitive(this->Name, RESUME_LIVE_RECONSTRUCTION_CMD))
350  {
351  LOG_INFO("Volume reconstruction from live frames resuming, device: " << reconstructorDeviceId);
352  if (reconstructorDevice->GetEnableReconstruction())
353  {
354  this->QueueCommandResponse(PLUS_FAIL, "Command failed. See error message.", baseMessage + " Reconstruction resume from live frames failed: live volume reconstruction is already in progress.");
355  return PLUS_FAIL;
356  }
357  reconstructorDevice->SetEnableReconstruction(true);
358  this->QueueCommandResponse(PLUS_SUCCESS, baseMessage + " Volume reconstruction from live frames resumed.");
359  return PLUS_SUCCESS;
360  }
361 
362  this->QueueCommandResponse(PLUS_FAIL, "Command failed. See error message.", baseMessage + "Unknown command name: " + this->Name + ".");
363  return PLUS_FAIL;
364 }
365 
366 //----------------------------------------------------------------------------
367 PlusStatus vtkPlusReconstructVolumeCommand::ProcessImageReply(vtkImageData* volumeToSend, const std::string& outputVolFilename, const std::string& outputVolDeviceName, std::string& resultMessage)
368 {
369  PlusStatus status = PLUS_SUCCESS;
370  resultMessage.clear();
371  if (!outputVolFilename.empty())
372  {
373  std::string outputVolFileFullPath = vtkPlusConfig::GetInstance()->GetOutputPath(outputVolFilename);
374  LOG_INFO("Saving reconstructed volume to file: " << outputVolFileFullPath);
375  if (vtkPlusVolumeReconstructor::SaveReconstructedVolumeToFile(volumeToSend, outputVolFileFullPath) != PLUS_SUCCESS)
376  {
377  status = PLUS_FAIL;
378  resultMessage += std::string("saving reconstructed volume to ") + outputVolFileFullPath + " failed";
379  }
380  else
381  {
382  resultMessage += std::string("saved reconstructed volume to file: ") + outputVolFileFullPath;
383  }
384  }
385  if (!outputVolDeviceName.empty())
386  {
387  // send the reconstructed volume with the reply
388  LOG_DEBUG("Send image to client through OpenIGTLink");
389  vtkSmartPointer<vtkPlusCommandImageResponse> imageResponse = vtkSmartPointer<vtkPlusCommandImageResponse>::New();
390  imageResponse->SetClientId(this->ClientId);
391  imageResponse->SetImageName(outputVolDeviceName);
392  imageResponse->SetImageData(volumeToSend);
393  vtkSmartPointer<vtkMatrix4x4> volumeToReferenceTransform = vtkSmartPointer<vtkMatrix4x4>::New();
394  imageResponse->SetImageToReferenceTransform(volumeToReferenceTransform);
395  volumeToReferenceTransform->Identity(); // we leave it as identity, as the volume coordinate system is, the same as the reference coordinate system (we may extend this later so that the client can request the volume in any coordinate system)
396  LOG_INFO("Send reconstructed volume to client through OpenIGTLink");
397  if (!resultMessage.empty())
398  {
399  resultMessage += ", ";
400  }
401  resultMessage += std::string("image sent as: ") + outputVolDeviceName;
402  this->CommandResponseQueue.push_back(imageResponse);
403  }
404  return status;
405 }
406 
407 //----------------------------------------------------------------------------
409 {
410  vtkPlusDataCollector* dataCollector = GetDataCollector();
411  if (dataCollector == NULL)
412  {
413  LOG_ERROR("Data collector is invalid");
414  return NULL;
415  }
416  vtkPlusVirtualVolumeReconstructor* reconstructorDevice = NULL;
417  if (!this->VolumeReconstructorDeviceId.empty())
418  {
419  // Reconstructor device ID is specified
420  vtkPlusDevice* device = NULL;
421  if (dataCollector->GetDevice(device, this->VolumeReconstructorDeviceId) != PLUS_SUCCESS)
422  {
423  LOG_ERROR("No volume reconstructor device has been found by the name " << this->VolumeReconstructorDeviceId);
424  return NULL;
425  }
426  // device found
427  reconstructorDevice = vtkPlusVirtualVolumeReconstructor::SafeDownCast(device);
428  if (reconstructorDevice == NULL)
429  {
430  // wrong type
431  LOG_ERROR("The specified device " << this->VolumeReconstructorDeviceId << " is not VirtualVolumeReconstructorDevice");
432  return NULL;
433  }
434  }
435  else
436  {
437  // No volume reconstruction device id is specified, auto-detect the first one and use that
438  for (DeviceCollectionConstIterator it = dataCollector->GetDeviceConstIteratorBegin(); it != dataCollector->GetDeviceConstIteratorEnd(); ++it)
439  {
440  reconstructorDevice = vtkPlusVirtualVolumeReconstructor::SafeDownCast(*it);
441  if (reconstructorDevice != NULL)
442  {
443  // found a recording device
444  break;
445  }
446  }
447  if (reconstructorDevice == NULL)
448  {
449  LOG_ERROR("No VirtualVolumeReconstructor has been found");
450  return NULL;
451  }
452  }
453  return reconstructorDevice;
454 }
vtkPlusVirtualVolumeReconstructor * GetVolumeReconstructorDevice()
std::string GetOutputPath(const std::string &subPath)
virtual void PrintSelf(ostream &os, vtkIndent indent)
Abstract interface for tracker and video devices.
Definition: vtkPlusDevice.h:60
std::vector< vtkPlusDevice * >::const_iterator DeviceCollectionConstIterator
Definition: vtkPlusDevice.h:48
virtual PlusStatus WriteConfiguration(vtkXMLDataElement *aConfig)
PlusStatus GetDevice(vtkPlusDevice *&aDevice, const std::string &aDeviceId) const
std::string Name
igsioStatus PlusStatus
Definition: PlusCommon.h:40
virtual PlusStatus ReadConfiguration(vtkXMLDataElement *aConfig)
virtual std::string GetDeviceId() const
virtual void PrintSelf(ostream &os, vtkIndent indent)
virtual PlusStatus SaveReconstructedVolumeToFile(const std::string &filename, bool accumulation=false, bool useCompression=true) override
virtual PlusStatus WriteConfiguration(vtkXMLDataElement *aConfig)
virtual void GetCommandNames(std::list< std::string > &cmdNames)
#define PLUS_FAIL
Definition: PlusCommon.h:43
static vtkPlusConfig * GetInstance()
DeviceCollectionConstIterator GetDeviceConstIteratorBegin() const
virtual PlusStatus GetReconstructedVolumeFromFile(const std::string &inputSeqFilename, vtkImageData *reconstructedVolume, std::string &errorMessage)
DeviceCollectionConstIterator GetDeviceConstIteratorEnd() const
Manages devices that record image or positional data.
#define PLUS_SUCCESS
Definition: PlusCommon.h:44
virtual long int GetTotalFramesRecorded()
virtual PlusStatus ReadConfiguration(vtkXMLDataElement *aConfig)
static vtkPlusVirtualVolumeReconstructor * SafeDownCast(vtkObject *o)
void QueueCommandResponse(PlusStatus status, const std::string &message, const std::string &error="", const igtl::MessageBase::MetaDataMap *metaData=nullptr)
virtual vtkPlusDataCollector * GetDataCollector()
virtual std::string GetDescription(const std::string &commandName)
This command reconstructs a volume from an image sequence and saves it to disk or sends it to the cli...
vtkStandardNewMacro(vtkPlusReconstructVolumeCommand)
PlusStatus GetReconstructedVolume(vtkImageData *reconstructedVolume, std::string &outErrorMessage, bool applyHoleFilling=true)
PlusStatus ProcessImageReply(vtkImageData *volumeToSend, const std::string &outputVolFilename, const std::string &outputVolDeviceName, std::string &resultMessage)
PlusCommandResponseList CommandResponseQueue
PlusStatus UpdateTransformRepository(vtkIGSIOTransformRepository *sharedTransformRepository)