13 #include "PlusConfigure.h" 22 #include <vtkAppendPolyData.h> 23 #include <vtkCubeSource.h> 24 #include <vtkMatrix4x4.h> 25 #include <vtkPolyData.h> 26 #include <vtkPolyDataWriter.h> 27 #include <vtkSTLWriter.h> 28 #include <vtkSmartPointer.h> 29 #include <vtkTransform.h> 30 #include <vtkTransformPolyDataFilter.h> 31 #include <vtkXMLUtilities.h> 32 #include <vtksys/CommandLineArguments.hxx> 35 #include <igsioTrackedFrame.h> 36 #include <vtkIGSIOSequenceIO.h> 37 #include <vtkIGSIOTrackedFrameList.h> 38 #include <vtkIGSIOTransformRepository.h> 43 int main(
int argc,
char** argv )
45 bool printHelp(
false );
46 std::string inputMetaFilename;
47 std::string inputConfigFileName;
48 std::string outputModelFilename;
49 std::string imageToReferenceTransformNameStr;
51 int verboseLevel = vtkPlusLogger::LOG_LEVEL_UNDEFINED;
53 vtksys::CommandLineArguments args;
54 args.Initialize( argc, argv );
56 args.AddArgument(
"--image-to-reference-transform", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &imageToReferenceTransformNameStr,
"Image to reference transform name used for creating slice models" );
57 args.AddArgument(
"--source-seq-file", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &inputMetaFilename,
"Tracked ultrasound recorded by Plus (e.g., by the TrackedUltrasoundCapturing application) in a sequence file (.mha/.nrrd)" );
58 args.AddArgument(
"--config-file", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &inputConfigFileName,
"Config file used for volume reconstruction. It contains the probe calibration matrix, the ImageToTool transform (.xml) " );
59 args.AddArgument(
"--output-model-file", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &outputModelFilename,
"A 3D model file that contains rectangles corresponding to each US image slice (.vtk)" );
60 args.AddArgument(
"--verbose", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &verboseLevel,
"Verbose level (1=error only, 2=warning, 3=info, 4=debug, 5=trace)" );
61 args.AddArgument(
"--help", vtksys::CommandLineArguments::NO_ARGUMENT, &printHelp,
"Print this help." );
65 std::cerr <<
"Problem parsing arguments" << std::endl;
66 std::cout <<
"Help: " << args.GetHelp() << std::endl;
72 std::cout << args.GetHelp() << std::endl;
78 if ( inputMetaFilename.empty() )
80 std::cerr <<
"--source-seq-file argument required!" << std::endl;
83 if ( outputModelFilename.empty() )
85 std::cerr <<
"--output-model-file argument required!" << std::endl;
86 std::cout <<
"Help: " << args.GetHelp() << std::endl;
91 LOG_DEBUG(
"Reading input... " );
92 vtkSmartPointer< vtkIGSIOTrackedFrameList > trackedFrameList = vtkSmartPointer< vtkIGSIOTrackedFrameList >::New();
93 if( vtkIGSIOSequenceIO::Read( inputMetaFilename, trackedFrameList ) !=
PLUS_SUCCESS )
95 LOG_ERROR(
"Unable to load input sequences file." );
98 LOG_DEBUG(
"Reading input done." );
99 LOG_DEBUG(
"Number of frames: " << trackedFrameList->GetNumberOfTrackedFrames() );
102 FrameSizeType clipRectangleOrigin = { 0, 0, 0 };
103 FrameSizeType clipRectangleSize = trackedFrameList->GetTrackedFrame(0)->GetFrameSize();
104 if (clipRectangleSize[0] <= 0 || clipRectangleSize[1] <= 0 )
106 LOG_ERROR(
"Invalid frame size: " << clipRectangleSize[0] <<
"x" << clipRectangleSize[1] );
107 clipRectangleSize[0] = 0;
108 clipRectangleSize[1] = 0;
112 vtkSmartPointer<vtkIGSIOTransformRepository> transformRepository = vtkSmartPointer<vtkIGSIOTransformRepository>::New();
113 if ( !inputConfigFileName.empty() )
115 LOG_DEBUG(
"Reading config file..." );
116 vtkSmartPointer<vtkXMLDataElement> configRootElement = vtkSmartPointer<vtkXMLDataElement>::New();
119 LOG_ERROR(
"Unable to read configuration from file " << inputConfigFileName.c_str() );
123 vtkSmartPointer<vtkPlusVolumeReconstructor> reconstructor = vtkSmartPointer<vtkPlusVolumeReconstructor>::New();
124 reconstructor->ReadConfiguration( configRootElement );
125 LOG_DEBUG(
"Reading config file done." );
126 if ( transformRepository->ReadConfiguration( configRootElement ) !=
PLUS_SUCCESS )
128 LOG_ERROR(
"Failed to read transforms for transform repository!" );
131 int* clipRectangleOriginInConfig = reconstructor->GetClipRectangleOrigin();
132 if ( clipRectangleOriginInConfig != NULL && clipRectangleOriginInConfig[0] >= 0 && clipRectangleOriginInConfig[1] >= 0 )
134 clipRectangleOrigin[0] = static_cast<unsigned int>(clipRectangleOriginInConfig[0]);
135 clipRectangleOrigin[1] = static_cast<unsigned int>(clipRectangleOriginInConfig[1]);
137 int* clipRectangleSizeInConfig = reconstructor->GetClipRectangleSize();
138 if ( clipRectangleSizeInConfig != NULL && clipRectangleSizeInConfig[0] > 0 && clipRectangleSizeInConfig[1] > 0 )
140 clipRectangleSize[0] = static_cast<unsigned int>(clipRectangleSizeInConfig[0]);
141 clipRectangleSize[1] = static_cast<unsigned int>(clipRectangleSizeInConfig[1]);
146 LOG_INFO(
"Configuration file is not specified. Only those transforms are available that are defined in the sequence metafile" );
150 vtkSmartPointer<vtkAppendPolyData> appender = vtkSmartPointer<vtkAppendPolyData>::New();
152 igsioTransformName imageToReferenceTransformName;
153 if ( imageToReferenceTransformName.SetTransformName( imageToReferenceTransformNameStr.c_str() ) !=
PLUS_SUCCESS )
155 LOG_ERROR(
"Invalid image to reference transform name: " << imageToReferenceTransformNameStr );
160 for (
unsigned int frameIndex = 0; frameIndex < trackedFrameList->GetNumberOfTrackedFrames(); ++ frameIndex )
162 igsioTrackedFrame* frame = trackedFrameList->GetTrackedFrame( frameIndex );
165 if ( transformRepository->SetTransforms( *frame ) !=
PLUS_SUCCESS )
167 LOG_ERROR(
"Failed to set repository transforms from tracked frame!" );
171 vtkSmartPointer<vtkMatrix4x4> imageToReferenceTransformMatrix = vtkSmartPointer<vtkMatrix4x4>::New();
172 if ( transformRepository->GetTransform( imageToReferenceTransformName, imageToReferenceTransformMatrix ) !=
PLUS_SUCCESS )
174 std::string strTransformName;
175 imageToReferenceTransformName.GetTransformName( strTransformName );
176 LOG_ERROR(
"Failed to get transform from repository: " << strTransformName );
180 vtkSmartPointer<vtkTransform> imageToReferenceTransform = vtkSmartPointer<vtkTransform>::New();
181 imageToReferenceTransform->SetMatrix( imageToReferenceTransformMatrix );
183 vtkSmartPointer<vtkTransform> tCubeToImage = vtkSmartPointer<vtkTransform>::New();
184 tCubeToImage->Translate( clipRectangleOrigin[0], clipRectangleOrigin[1], clipRectangleOrigin[2] );
185 tCubeToImage->Scale( clipRectangleSize[0], clipRectangleSize[1], clipRectangleSize[2] );
186 tCubeToImage->Translate( 0.5, 0.5, 0.5 );
188 vtkSmartPointer<vtkTransform> tCubeToTracker = vtkSmartPointer<vtkTransform>::New();
189 tCubeToTracker->Identity();
190 tCubeToTracker->Concatenate( imageToReferenceTransform );
191 tCubeToTracker->Concatenate( tCubeToImage );
193 vtkSmartPointer<vtkTransformPolyDataFilter> cubeToTracker = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
194 cubeToTracker->SetTransform( tCubeToTracker );
195 vtkSmartPointer<vtkCubeSource>
source = vtkSmartPointer<vtkCubeSource>::New();
197 cubeToTracker->SetInputConnection(
source->GetOutputPort() );
198 cubeToTracker->Update();
200 appender->AddInputConnection( cubeToTracker->GetOutputPort() );
204 LOG_DEBUG(
"Writing output model file (" << outputModelFilename <<
")..." );
205 std::string copy(outputModelFilename);
206 std::transform(copy.begin(), copy.end(), copy.begin(),
207 [](
unsigned char c) {
return std::tolower(c); });
208 if (copy.find(
"stl") != std::string::npos)
210 vtkSmartPointer<vtkSTLWriter> writer = vtkSmartPointer<vtkSTLWriter>::New();
211 writer->SetFileName(outputModelFilename.c_str());
212 writer->SetInputConnection(appender->GetOutputPort());
217 vtkSmartPointer<vtkPolyDataWriter> writer = vtkSmartPointer<vtkPolyDataWriter>::New();
218 writer->SetFileName(outputModelFilename.c_str());
219 writer->SetInputConnection(appender->GetOutputPort());
222 LOG_DEBUG(
"Writing model file done." );
224 LOG_INFO(
"Model file created: " << outputModelFilename );
int main(int argc, char **argv)
static vtkIGSIOLogger * Instance()
static PlusStatus ReadDeviceSetConfigurationFromFile(vtkXMLDataElement *config, const char *filename)