7 #include "PlusConfigure.h" 9 #include "vtkImageData.h" 10 #include "vtkObjectFactory.h" 14 #include "vtkIGSIOTrackedFrameList.h" 15 #include "vtkIGSIOTransformRepository.h" 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";
35 : ApplyHoleFilling(true)
59 SetName(RECONSTRUCT_PRERECORDED_CMD);
63 SetName(START_LIVE_RECONSTRUCTION_CMD);
67 SetName(STOP_LIVE_RECONSTRUCTION_CMD);
71 SetName(SUSPEND_LIVE_RECONSTRUCTION_CMD);
75 SetName(RESUME_LIVE_RECONSTRUCTION_CMD);
79 SetName(GET_LIVE_RECONSTRUCTION_SNAPSHOT_CMD);
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);
104 if (commandName.empty() || igsioCommon::IsEqualInsensitive(commandName, RECONSTRUCT_PRERECORDED_CMD))
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).";
109 if (commandName.empty() || igsioCommon::IsEqualInsensitive(commandName, START_LIVE_RECONSTRUCTION_CMD))
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).";
114 if (commandName.empty() || igsioCommon::IsEqualInsensitive(commandName, SUSPEND_LIVE_RECONSTRUCTION_CMD))
116 desc += SUSPEND_LIVE_RECONSTRUCTION_CMD;
117 desc +=
": Suspend adding acquired frames to the volume. Attributes: VolumeReconstructorDeviceId: ID of the volume reconstructor device.";
119 if (commandName.empty() || igsioCommon::IsEqualInsensitive(commandName, RESUME_LIVE_RECONSTRUCTION_CMD))
121 desc += RESUME_LIVE_RECONSTRUCTION_CMD;
122 desc +=
": Resume adding acquired frames to the volume. Attributes: VolumeReconstructorDeviceId: ID of the volume reconstructor device.";
124 if (commandName.empty() || igsioCommon::IsEqualInsensitive(commandName, STOP_LIVE_RECONSTRUCTION_CMD))
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).";
129 if (commandName.empty() || igsioCommon::IsEqualInsensitive(commandName, GET_LIVE_RECONSTRUCTION_SNAPSHOT_CMD))
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).";
148 this->SetVolumeReconstructorDeviceId(aConfig->GetAttribute(
"VolumeReconstructorDeviceId"));
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);
177 aConfig->SetVectorAttribute(
"OutputOrigin", 3, this->
OutputOrigin);
184 aConfig->SetVectorAttribute(
"OutputSpacing", 3, this->
OutputSpacing);
191 aConfig->SetVectorAttribute(
"OutputExtent", 6, this->
OutputExtent);
202 LOG_DEBUG(
"vtkPlusReconstructVolumeCommand::Execute: " << (!this->
Name.empty() ? this->
Name :
"(undefined)")
205 if (this->
Name.empty())
212 if (reconstructorDevice == NULL)
220 if (!this->GetOutputVolFilename().empty())
222 reconstructorDevice->SetOutputVolFilename(this->GetOutputVolFilename());
224 if (!this->GetOutputVolDeviceName().empty())
226 reconstructorDevice->SetOutputVolDeviceName(this->GetOutputVolDeviceName());
228 std::string outputVolFilename = (!reconstructorDevice->GetOutputVolFilename().empty() ? reconstructorDevice->GetOutputVolFilename() :
"");
229 std::string outputVolDeviceName = (!reconstructorDevice->GetOutputVolDeviceName().empty() ? reconstructorDevice->GetOutputVolDeviceName() :
"");
231 std::string reconstructorDeviceId = (reconstructorDevice->
GetDeviceId().empty() ?
"(unknown)" : reconstructorDevice->
GetDeviceId());
234 if (igsioCommon::IsEqualInsensitive(this->
Name, RECONSTRUCT_PRERECORDED_CMD) || igsioCommon::IsEqualInsensitive(this->
Name, START_LIVE_RECONSTRUCTION_CMD))
253 std::string baseMessage = this->
Name + std::string(
"(") + reconstructorDeviceId + std::string(
")");
254 if (igsioCommon::IsEqualInsensitive(this->
Name, RECONSTRUCT_PRERECORDED_CMD))
256 LOG_INFO(
"Volume reconstruction from sequence file: " << (!this->
InputSeqFilename.empty() ? this->
InputSeqFilename :
"(undefined)") <<
", device: " << reconstructorDeviceId);
259 this->
QueueCommandResponse(
PLUS_FAIL,
"Command failed. See error message.", baseMessage +
" Reconstruction from sequence file failed: live volume reconstruction is in progress.");
264 this->
QueueCommandResponse(
PLUS_FAIL,
"Command failed. See error message.", baseMessage +
" Reconstruction from sequence file failed: cannot get transform repository.");
267 reconstructorDevice->
Reset();
268 vtkSmartPointer<vtkImageData> volumeToSend = vtkSmartPointer<vtkImageData>::New();
269 std::string errorMessage;
272 this->
QueueCommandResponse(
PLUS_FAIL,
"Command failed. See error message.", baseMessage +
" Reconstruction from sequence file failed: " + errorMessage);
275 std::string 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);
280 else if (igsioCommon::IsEqualInsensitive(this->
Name, START_LIVE_RECONSTRUCTION_CMD))
282 LOG_INFO(
"Volume reconstruction from live frames starting, device: " << reconstructorDeviceId);
285 this->
QueueCommandResponse(
PLUS_FAIL,
"Command failed. See error message.", baseMessage +
" Reconstruction starting from live frames failed: live volume reconstruction is in progress.");
290 this->
QueueCommandResponse(
PLUS_FAIL,
"Command failed. See error message.", baseMessage +
" Reconstruction starting from live frames failed: cannot get transform repository.");
293 reconstructorDevice->
Reset();
298 else if (igsioCommon::IsEqualInsensitive(this->
Name, STOP_LIVE_RECONSTRUCTION_CMD))
303 this->
QueueCommandResponse(
PLUS_FAIL,
"Command failed. See error message.", baseMessage +
" Reconstruction stop from live frames failed: live volume reconstruction is already stopped, device.");
307 LOG_INFO(
"Volume reconstruction from live frames stopping, device: " << reconstructorDeviceId);
309 vtkSmartPointer<vtkImageData> volumeToSend = vtkSmartPointer<vtkImageData>::New();
310 std::string errorMessage;
313 this->
QueueCommandResponse(
PLUS_FAIL,
"Command failed. See error message.", baseMessage +
"Reconstruction stop from live frames failed: " + errorMessage);
316 reconstructorDevice->
Reset();
317 std::string 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);
322 else if (igsioCommon::IsEqualInsensitive(this->
Name, GET_LIVE_RECONSTRUCTION_SNAPSHOT_CMD))
324 LOG_INFO(
"Volume reconstruction from live frames snapshot request, device: " << reconstructorDeviceId);
325 vtkSmartPointer<vtkImageData> volumeToSend = vtkSmartPointer<vtkImageData>::New();
326 std::string errorMessage;
329 this->
QueueCommandResponse(
PLUS_FAIL,
"Command failed. See error message.", baseMessage +
" Reconstruction snapshot request failed, device: " + errorMessage);
332 std::string statusMessage;
334 this->
QueueCommandResponse(status, std::string(
"Command ") + std::string((status ==
PLUS_SUCCESS ?
"succeeded." :
"failed. See error message.")), baseMessage +
" " + statusMessage);
337 else if (igsioCommon::IsEqualInsensitive(this->
Name, SUSPEND_LIVE_RECONSTRUCTION_CMD))
339 LOG_INFO(
"Volume reconstruction from live frames suspending, device: " << reconstructorDeviceId);
342 this->
QueueCommandResponse(
PLUS_FAIL,
"Command failed. See error message.", baseMessage +
" Reconstruction suspend from live frames failed: live volume reconstruction is not in progress.");
349 else if (igsioCommon::IsEqualInsensitive(this->
Name, RESUME_LIVE_RECONSTRUCTION_CMD))
351 LOG_INFO(
"Volume reconstruction from live frames resuming, device: " << reconstructorDeviceId);
354 this->
QueueCommandResponse(
PLUS_FAIL,
"Command failed. See error message.", baseMessage +
" Reconstruction resume from live frames failed: live volume reconstruction is already in progress.");
370 resultMessage.clear();
371 if (!outputVolFilename.empty())
374 LOG_INFO(
"Saving reconstructed volume to file: " << outputVolFileFullPath);
378 resultMessage += std::string(
"saving reconstructed volume to ") + outputVolFileFullPath +
" failed";
382 resultMessage += std::string(
"saved reconstructed volume to file: ") + outputVolFileFullPath;
385 if (!outputVolDeviceName.empty())
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();
396 LOG_INFO(
"Send reconstructed volume to client through OpenIGTLink");
397 if (!resultMessage.empty())
399 resultMessage +=
", ";
401 resultMessage += std::string(
"image sent as: ") + outputVolDeviceName;
411 if (dataCollector == NULL)
413 LOG_ERROR(
"Data collector is invalid");
428 if (reconstructorDevice == NULL)
441 if (reconstructorDevice != NULL)
447 if (reconstructorDevice == NULL)
449 LOG_ERROR(
"No VirtualVolumeReconstructor has been found");
453 return reconstructorDevice;
vtkPlusVirtualVolumeReconstructor * GetVolumeReconstructorDevice()
void SetOutputExtent(int *extent)
std::string GetOutputPath(const std::string &subPath)
virtual void PrintSelf(ostream &os, vtkIndent indent)
Abstract interface for tracker and video devices.
std::vector< vtkPlusDevice * >::const_iterator DeviceCollectionConstIterator
virtual PlusStatus WriteConfiguration(vtkXMLDataElement *aConfig)
virtual PlusStatus Reset()
PlusStatus GetDevice(vtkPlusDevice *&aDevice, const std::string &aDeviceId) const
std::string InputSeqFilename
virtual PlusStatus ReadConfiguration(vtkXMLDataElement *aConfig)
virtual std::string GetDeviceId() const
std::string OutputVolDeviceName
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)
std::string VolumeReconstructorDeviceId
static vtkPlusConfig * GetInstance()
void SetOutputSpacing(double *spacing)
DeviceCollectionConstIterator GetDeviceConstIteratorBegin() const
std::string OutputVolFilename
virtual PlusStatus GetReconstructedVolumeFromFile(const std::string &inputSeqFilename, vtkImageData *reconstructedVolume, std::string &errorMessage)
vtkPlusReconstructVolumeCommand()
DeviceCollectionConstIterator GetDeviceConstIteratorEnd() const
Manages devices that record image or positional data.
virtual long int GetTotalFramesRecorded()
virtual ~vtkPlusReconstructVolumeCommand()
virtual PlusStatus ReadConfiguration(vtkXMLDataElement *aConfig)
static vtkPlusVirtualVolumeReconstructor * SafeDownCast(vtkObject *o)
virtual PlusStatus Execute()
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)
void SetNameToGetSnapshot()
PlusStatus ProcessImageReply(vtkImageData *volumeToSend, const std::string &outputVolFilename, const std::string &outputVolDeviceName, std::string &resultMessage)
void SetOutputOrigin(double *origin)
void SetNameToReconstruct()
void SetEnableReconstruction(bool aValue)
PlusCommandResponseList CommandResponseQueue
PlusStatus UpdateTransformRepository(vtkIGSIOTransformRepository *sharedTransformRepository)
virtual bool GetEnableReconstruction()