18 #ifndef __MILXDEFORMABLEMODEL_H 19 #define __MILXDEFORMABLEMODEL_H 22 #include <itkVTKPolyDataToMesh.h> 23 #include <itkMeshToVTKPolyData.h> 24 #include <itkLinearInterpolateImageFunction.h> 25 #ifdef ITK_USE_REVIEW //Review only members 26 #include <itkConformalFlatteningMeshFilter.h> 29 #include <vtkSmartPointer.h> 30 #include <vtkPolyData.h> 31 #include <vtkPointData.h> 32 #include <vtkFloatArray.h> 33 #include <vtkPolyDataToImageStencil.h> 34 #include <vtkImageStencil.h> 36 #include <milxGlobal.h> 38 #include <milxModel.h> 39 #include <milxImage.h> 83 template<
typename TImage>
84 void ApplyOrientation(itk::SmartPointer<TImage> image,
const bool applyOrigin =
true,
const bool flipY =
false);
93 template<
typename TImage>
94 itk::SmartPointer<TImage> VoxeliseAsITKImage(
const unsigned char insideValue,
double *spacing,
double *bounds = NULL,
const size_t padVoxels = 1);
99 template<
typename MeshType>
100 itk::SmartPointer<MeshType> ConvertVTKPolyDataToITKMesh();
105 template<
typename MeshType>
106 void ConvertITKMeshToVTKPolyData(itk::SmartPointer<MeshType> mesh);
107 #ifdef ITK_USE_REVIEW //Review only members 112 void Flatten(
const size_t flatMode = 1);
127 template<
typename TImage>
128 static vtkSmartPointer<vtkFloatArray> SurfaceScalarsFromImage(vtkSmartPointer<vtkPolyData> surface, itk::SmartPointer<TImage> img,
const bool absoluteValues);
134 template<
typename TImage>
135 static void MarkSurfaceInsideImage(vtkSmartPointer<vtkPolyData> &surface, itk::SmartPointer<TImage> img, vtkFloatArray *weights,
const float outsideValue = 0.0);
148 template<
typename TImage>
149 void ApplyOrientationCollection(vtkSmartPointer<vtkPolyDataCollection> collection, itk::SmartPointer<TImage> refImage,
const bool applyOrigin =
true,
const bool flipY =
false);
155 template<
typename TImage>
156 void VoxeliseCollection(vtkSmartPointer<vtkPolyDataCollection> collection,
const coordinateType spacing, std::vector<
typename itk::SmartPointer<TImage> > &images);
157 #ifdef ITK_USE_REVIEW //Review only members 162 void FlattenCollection(vtkSmartPointer<vtkPolyDataCollection> collection,
const size_t flatMode);
172 template<
typename TImage>
175 vtkSmartPointer<vtkImageData> img =
Model::Voxelise(insideValue, spacing, bounds, padVoxels);
180 template<
typename MeshType>
183 typedef itk::VTKPolyDataToMesh<MeshType> MeshFilterType;
184 typename MeshFilterType::Pointer filter = MeshFilterType::New();
185 filter->SetInput(CurrentModel);
188 std::cout <<
"Converting to ITK Mesh" << std::endl;
191 catch (itk::ExceptionObject & ex )
197 return filter->GetOutput();
200 template<
typename MeshType>
203 typedef itk::MeshToVTKPolyData<MeshType> MeshFilterType;
204 typename MeshFilterType::Pointer filter = MeshFilterType::New();
205 filter->SetInput(mesh);
208 std::cout <<
"Converting to VTK PolyData" << std::endl;
211 catch (itk::ExceptionObject & ex )
216 vtkSmartPointer<vtkPolyData> convMesh = filter->GetOutput();
218 CurrentModel->DeepCopy(convMesh);
219 std::cout <<
"Number of Points in VTK PolyData: " << CurrentModel->GetNumberOfPoints() << std::endl;
220 std::cout <<
"Number of Cells in VTK PolyData: " << CurrentModel->GetNumberOfCells() << std::endl;
223 #ifdef ITK_USE_REVIEW //Review only members 224 void DeformableModel::Flatten(
const size_t flatMode)
230 typedef itk::Mesh<vtkFloatingPointType, 3> MeshType;
231 itk::SmartPointer<MeshType> mesh = ConvertVTKPolyDataToITKMesh<MeshType>();
232 std::cout <<
"Number of Points in ITK Mesh: " << mesh->GetNumberOfPoints() << std::endl;
235 typedef itk::ConformalFlatteningMeshFilter<MeshType, MeshType> FlatFilterType;
236 FlatFilterType::Pointer filter = FlatFilterType::New();
237 filter->SetInput(mesh);
240 filter->MapToPlane();
242 filter->MapToSphere();
245 std::cout <<
"Trying to flatten..." << std::endl;
248 catch (itk::ExceptionObject & ex )
253 itk::SmartPointer<MeshType> flatMesh = filter->GetOutput();
256 ConvertITKMeshToVTKPolyData<MeshType>(flatMesh);
260 template<
typename TImage>
264 typename TImage::DirectionType direction = image->GetDirection();
265 typename TImage::PointType origin = image->GetOrigin();
269 vtkSmartPointer<vtkMatrix4x4> flipMatrix = vtkSmartPointer<vtkMatrix4x4>::New();
270 flipMatrix->Identity();
273 flipMatrix->SetElement(1,1,-1);
275 std::cout <<
"Direction to be applied:\n" << direction << std::endl;
276 vtkSmartPointer<vtkMatrix4x4> matrix = vtkSmartPointer<vtkMatrix4x4>::New();
278 for (
int i = 0; i < 3; i ++)
279 for (
int k = 0; k < 3; k ++)
280 matrix->SetElement(i,k, direction(i,k));
282 vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New();
283 transform->Identity();
284 transform->PostMultiply();
285 transform->Concatenate(flipMatrix);
286 transform->Translate(-centroid[0], -centroid[1], -centroid[2]);
287 transform->Concatenate(matrix);
289 transform->Translate(origin.GetDataPointer());
294 template<
typename TImage>
297 const int numberOfPoints = surface->GetNumberOfPoints();
299 typedef itk::Point<double, 3> InputImagePointType;
300 typedef itk::ContinuousIndex<double, 3 > ContinuousIndexType;
302 typedef itk::LinearInterpolateImageFunction<TImage, double> InterpolatorType;
303 typename InterpolatorType::Pointer interpolator = InterpolatorType::New();
304 interpolator->SetInputImage(img);
306 vtkSmartPointer<vtkFloatArray> scalars = vtkSmartPointer<vtkFloatArray>::New();
307 scalars->SetName(
"Distance");
308 scalars->SetNumberOfTuples(numberOfPoints);
309 scalars->SetNumberOfComponents(1);
312 InputImagePointType point;
313 ContinuousIndexType index;
314 for(
int i = 0; i < numberOfPoints; i++)
317 surface->GetPoint(i, position);
319 point[0] = position[0];
320 point[1] = position[1];
321 point[2] = position[2];
323 img->TransformPhysicalPointToContinuousIndex(point, index);
326 if(interpolator->IsInsideBuffer(index))
328 double valueFound = 0.0;
330 valueFound = fabs(interpolator->EvaluateAtContinuousIndex(index));
332 valueFound = interpolator->EvaluateAtContinuousIndex(index);
333 scalars->SetTuple1(i, valueFound);
340 template<
typename TImage>
343 const int numberOfPoints = surface->GetNumberOfPoints();
344 vtkSmartPointer<vtkFloatArray> surfaceWeights = vtkFloatArray::SafeDownCast(surface->GetPointData()->GetScalars());
345 bool hasScalars =
false;
349 typedef itk::Point<double, 3> InputImagePointType;
350 typedef itk::ContinuousIndex<double, 3> ContinuousIndexType;
352 weights->SetName(
"Weights");
353 weights->SetNumberOfTuples(numberOfPoints);
354 weights->SetNumberOfComponents(1);
355 weights->FillComponent(0, outsideValue);
357 typedef itk::LinearInterpolateImageFunction<TImage, double> InterpolatorType;
358 typename InterpolatorType::Pointer interpolator = InterpolatorType::New();
359 interpolator->SetInputImage(img);
363 InputImagePointType point;
364 ContinuousIndexType index;
365 for(
int i = 0; i < numberOfPoints; i++)
368 surface->GetPoint(i, position);
370 point[0] = position[0];
371 point[1] = position[1];
372 point[2] = position[2];
374 img->TransformPhysicalPointToContinuousIndex(point, index);
377 if(interpolator->IsInsideBuffer(index))
380 weights->SetTuple1(i, surfaceWeights->GetTuple1(i));
382 weights->SetTuple1(i, 1.0);
386 surface->GetPointData()->SetScalars(weights);
390 template<
typename TImage>
393 const size_t n = collection->GetNumberOfItems();
394 InternalInPlaceOperation =
true;
396 collection->InitTraversal();
397 for(
size_t j = 0; j < n; j ++)
399 vtkSmartPointer<vtkPolyData> mesh = collection->GetNextItem();
401 ApplyOrientation<TImage>(refImage, applyOrigin, flipY);
405 InternalInPlaceOperation =
false;
408 template<
typename TImage>
411 const size_t n = collection->GetNumberOfItems();
412 double isoSpacing[3];
413 InternalInPlaceOperation =
true;
415 isoSpacing[0] = spacing;
416 isoSpacing[1] = spacing;
417 isoSpacing[2] = spacing;
420 collection->InitTraversal();
421 for(
size_t j = 0; j < n; j ++)
423 vtkSmartPointer<vtkPolyData> mesh = collection->GetNextItem();
425 itk::SmartPointer<TImage> img = VoxeliseAsITKImage<TImage>(1, isoSpacing);
426 images.push_back(img);
429 InternalInPlaceOperation =
false;
432 #ifdef ITK_USE_REVIEW //Review only members 433 void DeformableModel::FlattenCollection(vtkSmartPointer<vtkPolyDataCollection> collection,
const size_t flatMode)
435 const size_t n = collection->GetNumberOfItems();
436 InternalInPlaceOperation =
true;
438 collection->InitTraversal();
439 for(
size_t j = 0; j < n; j ++)
441 vtkSmartPointer<vtkPolyData> mesh = collection->GetNextItem();
447 InternalInPlaceOperation =
false;
453 #endif //__MILXDEFORMABLEMODEL_H static Type Centroid(const vnl_vector< Type > &data)
Compute the centroid (or the mean) of a data vector.
itk::SmartPointer< TImage > VoxeliseAsITKImage(const unsigned char insideValue, double *spacing, double *bounds=NULL, const size_t padVoxels=1)
Convert a model to voxelised (imaging) data.
static itk::SmartPointer< TImage > ConvertVTKImageToITKImage(vtkSmartPointer< vtkImageData > img)
Converts a VTK image object to an ITK image object.
void PrintError(const std::string msg)
Displays a generic msg to standard error with carriage return.
#define SMILI_EXPORT
DLL Function Symbol for Windows. It is empty for other OSes.
vtkSmartPointer< vtkPolyData > & Result()
Returns the current model, i.e. the result of the latest operation.
void SetInput(vtkSmartPointer< vtkPolyData > model)
Assigns the input model to class.
void SetTransform(vtkSmartPointer< vtkAbstractTransform > newTransform)
Transforms the model by given transform.
itk::SmartPointer< MeshType > ConvertVTKPolyDataToITKMesh()
Convert the current vtkPolyData to an itk::Mesh.
void ConvertITKMeshToVTKPolyData(itk::SmartPointer< MeshType > mesh)
Convert an itk::Mesh to the current vtkPolyData.
vtkSmartPointer< vtkImageData > Voxelise(const unsigned char insideValue, double *spacing, double *bounds=NULL, const size_t padVoxels=1)
static void MarkSurfaceInsideImage(vtkSmartPointer< vtkPolyData > &surface, itk::SmartPointer< TImage > img, vtkFloatArray *weights, const float outsideValue=0.0)
Mark existing surface with all parts outside the image as 'outsideValue' value. Inside will remain th...
static vtkSmartPointer< vtkFloatArray > SurfaceScalarsFromImage(vtkSmartPointer< vtkPolyData > surface, itk::SmartPointer< TImage > img, const bool absoluteValues)
Returns the scalars of the mesh (float values per vertex) according to the values found within the im...
Represents a model (i.e. a model with cells and scalar values) and their common operations. Also allows batch operations on collection of models.
void ApplyOrientation(itk::SmartPointer< TImage > image, const bool applyOrigin=true, const bool flipY=false)
Apply the orientation of an image to a model.