24 #include "milxModel.h" 27 #include <vtkAppendPolyData.h> 28 #include <vtkLandmarkTransform.h> 29 #include <vtkProcrustesAlignmentFilter.h> 30 #include <vtkAppendPolyData.h> 31 #include <vtkGraphToPolyData.h> 32 #include <vtkDoubleArray.h> 34 #include <vtkTriangle.h> 36 #include <vtkCleanPolyData.h> 37 #include <vtkTriangleFilter.h> 38 #include <vtkDecimatePro.h> 39 #include <vtkQuadricDecimation.h> 40 #include <vtkQuadricClustering.h> 41 #include <vtkSmoothPolyDataFilter.h> 42 #include <vtkWindowedSincPolyDataFilter.h> 43 #include <vtkTransformPolyDataFilter.h> 44 #include <vtkIterativeClosestPointTransform.h> 45 #include <vtkLandmarkTransform.h> 46 #include <vtkCurvatures.h> 47 #include <vtkGradientFilter.h> 48 #include <vtkAssignAttribute.h> 49 #include <vtkSelectPolyData.h> 50 #include <vtkPolyDataToImageStencil.h> 51 #include <vtkImageStencil.h> 52 #include <vtkRotationFilter.h> 53 #include <vtkReflectionFilter.h> 54 #include <vtkThreshold.h> 55 #include <vtkGeometryFilter.h> 56 #include <vtkDelaunay3D.h> 57 #include <vtkDelaunay2D.h> 58 #include <vtkExtractEdges.h> 59 #include <vtkTubeFilter.h> 60 #include <vtkVertexGlyphFilter.h> 61 #include <vtkIdFilter.h> 62 #include <vtkGlyph3D.h> 63 #include <vtkPolyDataPointSampler.h> 64 #include <vtkTensorGlyph.h> 65 #include <vtkHedgeHog.h> 66 #include <vtkPolyDataNormals.h> 67 #include <vtkFeatureEdges.h> 68 #include <vtkStripper.h> 69 #include <vtkConnectivityFilter.h> 70 #include <vtkSimpleElevationFilter.h> 71 #include <vtkElevationFilter.h> 72 #include <vtkKMeansStatistics.h> 73 #include <vtkQuantizePolyDataPoints.h> 79 #include <vtkGlyphSource2D.h> 80 #include <vtkSphereSource.h> 81 #include <vtkArrowSource.h> 83 #include <vtkImageFlip.h> 84 #include <vtkImageMarchingCubes.h> 85 #if VTK_MAJOR_VERSION > 5 86 #include <vtkMultiBlockDataSet.h> 87 #include <vtkMultiBlockDataGroupFilter.h> 94 typedef vtkDoubleArray milxArrayType;
113 vtkSmartPointer<vtkAppendPolyData> appendPolyData = vtkSmartPointer<vtkAppendPolyData>::New();
114 #if (VTK_MAJOR_VERSION > 5) 117 appendPolyData->AddInputData(model);
121 appendPolyData->AddInput(model);
123 if(VTKProgressUpdates->IsBeingObserved())
124 appendPolyData->AddObserver(vtkCommand::ProgressEvent, VTKProgressUpdates);
125 appendPolyData->Update();
127 UpdateModelState(appendPolyData);
145 if(!IsCurrentModel())
154 vtkSmartPointer<vtkTransform> linearTransform = vtkTransform::SafeDownCast(newTransform);
162 vtkSmartPointer<vtkTransformPolyDataFilter> transformedMesh = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
163 #if VTK_MAJOR_VERSION <= 5 168 transformedMesh->SetTransform(newTransform);
169 if(VTKProgressUpdates->IsBeingObserved())
170 transformedMesh->AddObserver(vtkCommand::ProgressEvent, VTKProgressUpdates);
171 transformedMesh->Update();
173 UpdateModelState(transformedMesh);
181 vtkSmartPointer<vtkGraphToPolyData> graphPolyData = vtkSmartPointer<vtkGraphToPolyData>::New();
182 #if VTK_MAJOR_VERSION <= 5 183 graphPolyData->SetInput(graph);
185 graphPolyData->SetInputData(graph);
187 if(VTKProgressUpdates->IsBeingObserved())
188 graphPolyData->AddObserver(vtkCommand::ProgressEvent, VTKProgressUpdates);
189 graphPolyData->Update();
191 UpdateModelState(graphPolyData);
204 if(!IsCurrentModel())
212 if(!IsCurrentModel())
220 if(!IsCurrentModel())
234 CurrentModel->GetPointData()->GetScalars()->FillComponent(0, value);
237 vtkSmartPointer<milxArrayType> scalars = vtkSmartPointer<milxArrayType>::New();
238 scalars->SetName(
"Reset Scalars");
239 scalars->SetNumberOfTuples(
CurrentModel->GetNumberOfPoints());
240 scalars->SetNumberOfComponents(1);
241 scalars->FillComponent(0, value);
251 #if (VTK_MAJOR_VERSION == 5 && VTK_MINOR_VERSION < 8) 252 mesh->GetPointData()->SetActiveScalars(NULL);
254 const int n = mesh->GetPointData()->GetNumberOfArrays();
256 for(
int j = 0; j < n; j ++)
259 if(mesh->GetPointData()->GetArray(n-1-j)->GetNumberOfComponents() == 1)
260 mesh->GetPointData()->RemoveArray(n-1-j);
267 vtkSmartPointer<vtkPolyData> mesh = vtkSmartPointer<vtkPolyData>::New();
272 UpdateModelStateFromModel(mesh);
277 vtkSmartPointer<vtkPolyData> mesh = vtkSmartPointer<vtkPolyData>::New();
282 UpdateModelStateFromModel(mesh);
288 if(!IsCurrentModel())
292 vtkSmartPointer<vtkCleanPolyData> cleanFilter = vtkSmartPointer<vtkCleanPolyData>::New();
293 #if VTK_MAJOR_VERSION <= 5 298 if(VTKProgressUpdates->IsBeingObserved())
299 cleanFilter->AddObserver(vtkCommand::ProgressEvent, VTKProgressUpdates);
300 cleanFilter->Update();
302 UpdateModelState(cleanFilter);
307 if(!IsCurrentModel())
311 vtkSmartPointer<vtkTriangleFilter> triangulate = vtkSmartPointer<vtkTriangleFilter>::New();
312 #if VTK_MAJOR_VERSION <= 5 317 if(VTKProgressUpdates->IsBeingObserved())
318 triangulate->AddObserver(vtkCommand::ProgressEvent, VTKProgressUpdates);
319 triangulate->Update();
321 UpdateModelState(triangulate);
326 if(!IsCurrentModel())
333 coordinate newCentroid = otherCentroid - modelCentroid;
335 coordinateType newCentroid[3];
336 newCentroid[0] = otherCentroid[0] - modelCentroid[0];
337 newCentroid[1] = otherCentroid[1] - modelCentroid[1];
338 newCentroid[2] = otherCentroid[2] - modelCentroid[2];
344 double scaling = otherScale/modelScale;
346 vtkSmartPointer<vtkTransform> transformer = vtkSmartPointer<vtkTransform>::New();
347 transformer->Translate(newCentroid[0], newCentroid[1], newCentroid[2]);
349 transformer->Scale(scaling, scaling, scaling);
354 delete modelCentroid;
355 delete otherCentroid;
361 if(!IsCurrentModel())
365 vtkSmartPointer<vtkIterativeClosestPointTransform> icp = vtkSmartPointer<vtkIterativeClosestPointTransform>::New();
367 icp->SetTarget(fixedMesh);
368 icp->CheckMeanDistanceOn();
369 icp->StartByMatchingCentroidsOn();
370 icp->SetMaximumMeanDistance(0.001);
371 icp->SetMaximumNumberOfIterations(300);
372 icp->SetMaximumNumberOfLandmarks(maxPoints);
373 icp->GetLandmarkTransform()->SetModeToRigidBody();
374 if(VTKProgressUpdates->IsBeingObserved())
375 icp->AddObserver(vtkCommand::ProgressEvent, VTKProgressUpdates);
377 icp->GetLandmarkTransform()->SetModeToSimilarity();
380 vtkMatrix4x4* transformMatrix = icp->GetMatrix();
381 vtkSmartPointer<vtkTransform> transformer = vtkSmartPointer<vtkTransform>::New();
382 transformer->SetMatrix(transformMatrix);
389 if(!IsCurrentModel())
392 if(
CurrentModel->GetNumberOfPoints() != fixedMesh->GetNumberOfPoints())
394 PrintError(
"Landmark-based registration requires equal number of points. Ignoring Operation.");
399 vtkSmartPointer<vtkLandmarkTransform> landmarkTransform = vtkSmartPointer<vtkLandmarkTransform>::New();
400 landmarkTransform->SetModeToRigidBody();
402 landmarkTransform->SetModeToSimilarity();
403 landmarkTransform->SetSourceLandmarks(
CurrentModel->GetPoints());
404 landmarkTransform->SetTargetLandmarks(fixedMesh->GetPoints());
405 if(VTKProgressUpdates->IsBeingObserved())
406 landmarkTransform->AddObserver(vtkCommand::ProgressEvent, VTKProgressUpdates);
407 landmarkTransform->Update();
409 vtkMatrix4x4* transformMatrix = landmarkTransform->GetMatrix();
410 vtkSmartPointer<vtkTransform> transformer = vtkSmartPointer<vtkTransform>::New();
411 transformer->SetMatrix(transformMatrix);
421 vtkSmartPointer<vtkDecimatePro> decimateFilter = vtkSmartPointer<vtkDecimatePro>::New();
422 #if VTK_MAJOR_VERSION <= 5 427 decimateFilter->SetTargetReduction(reduceFactor);
428 if(VTKProgressUpdates->IsBeingObserved())
429 decimateFilter->AddObserver(vtkCommand::ProgressEvent, VTKProgressUpdates);
430 decimateFilter->Update();
432 UpdateModelState(decimateFilter);
440 vtkSmartPointer<vtkQuadricDecimation> decimateFilter = vtkSmartPointer<vtkQuadricDecimation>::New();
441 #if VTK_MAJOR_VERSION <= 5 446 decimateFilter->SetTargetReduction(reduceFactor);
447 if(VTKProgressUpdates->IsBeingObserved())
448 decimateFilter->AddObserver(vtkCommand::ProgressEvent, VTKProgressUpdates);
449 decimateFilter->Update();
451 UpdateModelState(decimateFilter);
459 vtkSmartPointer<vtkQuadricClustering> decimateFilter = vtkSmartPointer<vtkQuadricClustering>::New();
460 #if VTK_MAJOR_VERSION <= 5 465 decimateFilter->AutoAdjustNumberOfDivisionsOn();
466 if(VTKProgressUpdates->IsBeingObserved())
467 decimateFilter->AddObserver(vtkCommand::ProgressEvent, VTKProgressUpdates);
468 decimateFilter->Update();
470 UpdateModelState(decimateFilter);
475 if(!IsCurrentModel())
479 vtkSmartPointer<vtkSmoothPolyDataFilter> smoothFilter = vtkSmartPointer<vtkSmoothPolyDataFilter>::New();
480 #if VTK_MAJOR_VERSION <= 5 485 smoothFilter->SetNumberOfIterations(iterations);
486 if(VTKProgressUpdates->IsBeingObserved())
487 smoothFilter->AddObserver(vtkCommand::ProgressEvent, VTKProgressUpdates);
488 smoothFilter->Update();
490 UpdateModelState(smoothFilter);
495 if(!IsCurrentModel())
499 vtkSmartPointer<vtkWindowedSincPolyDataFilter> smoothFilter = vtkSmartPointer<vtkWindowedSincPolyDataFilter>::New();
500 #if VTK_MAJOR_VERSION <= 5 505 smoothFilter->SetNumberOfIterations(iterations);
506 smoothFilter->SetPassBand(passBand);
507 if(VTKProgressUpdates->IsBeingObserved())
508 smoothFilter->AddObserver(vtkCommand::ProgressEvent, VTKProgressUpdates);
509 smoothFilter->Update();
511 UpdateModelState(smoothFilter);
516 if(!IsCurrentModel())
519 vtkSmartPointer<vtkCurvatures> curvatureFilter = vtkSmartPointer<vtkCurvatures>::New();
520 #if VTK_MAJOR_VERSION <= 5 525 curvatureFilter->SetCurvatureTypeToMean();
528 curvatureFilter->SetCurvatureTypeToMaximum();
530 if(VTKProgressUpdates->IsBeingObserved())
531 curvatureFilter->AddObserver(vtkCommand::ProgressEvent, VTKProgressUpdates);
532 curvatureFilter->Update();
534 UpdateModelState(curvatureFilter);
539 if(!IsCurrentModel() || !
CurrentModel->GetPointData()->GetScalars())
542 vtkSmartPointer<vtkGradientFilter> gradientFilter = vtkSmartPointer<vtkGradientFilter>::New();
543 #if VTK_MAJOR_VERSION <= 5 548 if(VTKProgressUpdates->IsBeingObserved())
549 gradientFilter->AddObserver(vtkCommand::ProgressEvent, VTKProgressUpdates);
551 vtkSmartPointer<vtkGeometryFilter> geometry = vtkSmartPointer<vtkGeometryFilter>::New();
552 geometry->SetInputConnection(gradientFilter->GetOutputPort());
554 vtkSmartPointer<vtkAssignAttribute> vectors = vtkSmartPointer<vtkAssignAttribute>::New();
555 vectors->SetInputConnection(geometry->GetOutputPort());
556 vectors->Assign(
"Gradients", vtkDataSetAttributes::VECTORS, vtkAssignAttribute::POINT_DATA);
559 UpdateModelStateFromModel(vectors->GetPolyDataOutput());
564 if(!IsCurrentModel())
567 vtkSmartPointer<vtkSelectPolyData> selection = vtkSmartPointer<vtkSelectPolyData>::New();
568 #if VTK_MAJOR_VERSION <= 5 573 selection->SetLoop(loopPoints);
574 selection->GenerateSelectionScalarsOn();
575 selection->SetSelectionModeToSmallestRegion();
577 if(VTKProgressUpdates->IsBeingObserved())
578 selection->AddObserver(vtkCommand::ProgressEvent, VTKProgressUpdates);
581 UpdateModelState(selection);
589 vtkSmartPointer<vtkPolyData> mesh = vtkSmartPointer<vtkPolyData>::New();
592 vtkSmartPointer<vtkDataArray> scalars = mesh->GetPointData()->GetScalars();
594 const int n = mesh->GetNumberOfPoints();
595 const float stddevSquared = 0.5*stddev*stddev;
596 for(
int j = 0; j < n; j ++)
598 double *value = scalars->GetTuple(j);
599 value[0] = exp(-value[0]*value[0]/stddevSquared);
600 if(value[0] < clampValue)
601 value[0] = clampValue;
602 scalars->SetTuple(j, value);
605 UpdateModelStateFromModel(mesh);
608 void Model::Rotate(
const bool xAxis,
const bool yAxis,
const bool zAxis,
const float angle,
const coordinate centre)
610 if(!IsCurrentModel())
613 vtkSmartPointer<vtkRotationFilter> rotator = vtkSmartPointer<vtkRotationFilter>::New();
614 #if VTK_MAJOR_VERSION <= 5 619 if(VTKProgressUpdates->IsBeingObserved())
620 rotator->AddObserver(vtkCommand::ProgressEvent, VTKProgressUpdates);
621 rotator->CopyInputOff();
623 rotator->SetAxisToX();
625 rotator->SetAxisToY();
627 rotator->SetAxisToZ();
628 rotator->SetAngle(angle);
629 rotator->SetCenter(centre[0], centre[1], centre[2]);
630 rotator->SetNumberOfCopies(1);
634 vtkSmartPointer<vtkGeometryFilter> region = vtkSmartPointer<vtkGeometryFilter>::New();
635 region->SetInputConnection(rotator->GetOutputPort());
636 if(VTKProgressUpdates->IsBeingObserved())
637 region->AddObserver(vtkCommand::ProgressEvent, VTKProgressUpdates);
640 UpdateModelState(region);
643 void Model::Flip(
const bool xAxis,
const bool yAxis,
const bool zAxis)
645 if(!IsCurrentModel())
648 vtkSmartPointer<vtkReflectionFilter> flipper = vtkSmartPointer<vtkReflectionFilter>::New();
649 #if VTK_MAJOR_VERSION <= 5 654 if(VTKProgressUpdates->IsBeingObserved())
655 flipper->AddObserver(vtkCommand::ProgressEvent, VTKProgressUpdates);
656 flipper->CopyInputOff();
658 flipper->SetPlaneToX();
660 flipper->SetPlaneToY();
662 flipper->SetPlaneToZ();
666 vtkSmartPointer<vtkGeometryFilter> region = vtkSmartPointer<vtkGeometryFilter>::New();
667 region->SetInputConnection(flipper->GetOutputPort());
668 if(VTKProgressUpdates->IsBeingObserved())
669 region->AddObserver(vtkCommand::ProgressEvent, VTKProgressUpdates);
672 UpdateModelState(region);
675 void Model::Clip(
const coordinateType belowValue,
const coordinateType aboveValue)
677 if(!IsCurrentModel())
680 vtkSmartPointer<vtkThreshold> thresh = vtkSmartPointer<vtkThreshold>::New();
681 #if VTK_MAJOR_VERSION <= 5 688 thresh->ThresholdBetween(belowValue, aboveValue);
689 if(VTKProgressUpdates->IsBeingObserved())
690 thresh->AddObserver(vtkCommand::ProgressEvent, VTKProgressUpdates);
693 vtkSmartPointer<vtkGeometryFilter> region = vtkSmartPointer<vtkGeometryFilter>::New();
694 region->SetInputConnection(thresh->GetOutputPort());
695 if(VTKProgressUpdates->IsBeingObserved())
696 region->AddObserver(vtkCommand::ProgressEvent, VTKProgressUpdates);
699 UpdateModelState(region);
702 void Model::Threshold(
const coordinateType belowVal,
const coordinateType aboveVal,
const coordinateType outsideVal)
704 if(!IsCurrentModel())
707 vtkSmartPointer<vtkPolyData> newMesh = vtkSmartPointer<vtkPolyData>::New();
713 UpdateModelStateFromModel(newMesh);
716 void Model::Threshold(
const coordinateType belowVal,
const coordinateType aboveVal,
const coordinateType insideVal,
const coordinateType outsideVal)
718 if(!IsCurrentModel())
721 vtkSmartPointer<vtkPolyData> newMesh = vtkSmartPointer<vtkPolyData>::New();
727 UpdateModelStateFromModel(newMesh);
732 if(!IsCurrentModel())
735 vtkSmartPointer<vtkPolyData> newMesh = vtkSmartPointer<vtkPolyData>::New();
741 UpdateModelStateFromModel(newMesh);
746 vtkSmartPointer<vtkImageMarchingCubes> iso = vtkSmartPointer<vtkImageMarchingCubes>::New();
747 #if VTK_MAJOR_VERSION <= 5 750 iso->SetInputData(img);
752 iso->SetValue(0, minValue);
753 iso->ComputeNormalsOn();
754 iso->ComputeScalarsOff();
756 if(VTKProgressUpdates->IsBeingObserved())
757 iso->AddObserver(vtkCommand::ProgressEvent, VTKProgressUpdates);
760 if(!IsCurrentModel())
763 UpdateModelState(iso);
766 vtkSmartPointer<vtkImageData>
Model::Voxelise(
const unsigned char insideValue,
double *spacing,
double *bounds,
const size_t padVoxels)
768 if(!IsCurrentModel())
771 vtkSmartPointer<vtkImageData> whiteImage = vtkSmartPointer<vtkImageData>::New();
773 double totalBounds[6];
776 bounds = &totalBounds[0];
779 whiteImage->SetSpacing(spacing);
782 bounds[0] -= padVoxels*spacing[0];
783 bounds[1] += padVoxels*spacing[0];
784 bounds[2] -= padVoxels*spacing[1];
785 bounds[3] += padVoxels*spacing[1];
786 bounds[4] -= padVoxels*spacing[2];
787 bounds[5] += padVoxels*spacing[2];
791 for (
int i = 0; i < 3; i++)
793 dim[i] =
static_cast<int>( ceil((bounds[i * 2 + 1] - bounds[i * 2]) / spacing[i]) );
796 whiteImage->SetDimensions(dim);
797 whiteImage->SetExtent(0, dim[0] - 1, 0, dim[1] - 1, 0, dim[2] - 1);
801 origin[0] = bounds[0];
802 origin[1] = bounds[2];
803 origin[2] = bounds[4];
804 whiteImage->SetOrigin(origin);
805 #if VTK_MAJOR_VERSION <= 5 806 whiteImage->SetNumberOfScalarComponents(1);
807 whiteImage->SetScalarTypeToUnsignedChar();
808 whiteImage->AllocateScalars();
810 whiteImage->AllocateScalars(VTK_UNSIGNED_CHAR,1);
814 unsigned char inval = insideValue;
815 unsigned char outval = 0;
816 for (vtkIdType i = 0; i < whiteImage->GetNumberOfPoints(); ++i)
817 whiteImage->GetPointData()->GetScalars()->SetTuple1(i, inval);
820 PrintDebug(
"Polygonal data --> Image stencil");
821 vtkSmartPointer<vtkPolyDataToImageStencil> pol2stenc = vtkSmartPointer<vtkPolyDataToImageStencil>::New();
822 #if VTK_MAJOR_VERSION <= 5 827 pol2stenc->SetOutputOrigin(origin);
828 pol2stenc->SetOutputSpacing(spacing);
829 pol2stenc->SetOutputWholeExtent(whiteImage->GetExtent());
830 if(VTKProgressUpdates->IsBeingObserved())
831 pol2stenc->AddObserver(vtkCommand::ProgressEvent, VTKProgressUpdates);
836 vtkSmartPointer<vtkImageStencil> imgstenc = vtkSmartPointer<vtkImageStencil>::New();
837 #if VTK_MAJOR_VERSION <= 5 838 imgstenc->SetInput(whiteImage);
839 imgstenc->SetStencil(pol2stenc->GetOutput());
841 imgstenc->SetInputData(whiteImage);
842 imgstenc->SetStencilConnection(pol2stenc->GetOutputPort());
844 imgstenc->ReverseStencilOff();
845 imgstenc->SetBackgroundValue(outval);
846 if(VTKProgressUpdates->IsBeingObserved())
847 imgstenc->AddObserver(vtkCommand::ProgressEvent, VTKProgressUpdates);
850 return imgstenc->GetOutput();
855 if(!IsCurrentModel())
859 vtkSmartPointer<vtkDelaunay3D> delaunay = vtkSmartPointer<vtkDelaunay3D>::New();
860 #if VTK_MAJOR_VERSION <= 5 865 if(VTKProgressUpdates->IsBeingObserved())
866 delaunay->AddObserver(vtkCommand::ProgressEvent, VTKProgressUpdates);
869 vtkSmartPointer<vtkExtractEdges> extract = vtkSmartPointer<vtkExtractEdges>::New();
870 extract->SetInputConnection(delaunay->GetOutputPort());
871 if(VTKProgressUpdates->IsBeingObserved())
872 extract->AddObserver(vtkCommand::ProgressEvent, VTKProgressUpdates);
874 vtkSmartPointer<vtkTubeFilter> tubes = vtkSmartPointer<vtkTubeFilter>::New();
875 tubes->SetInputConnection(extract->GetOutputPort());
876 tubes->SetRadius(0.02);
877 tubes->SetNumberOfSides(3);
878 if(VTKProgressUpdates->IsBeingObserved())
879 tubes->AddObserver(vtkCommand::ProgressEvent, VTKProgressUpdates);
882 UpdateModelState(tubes);
887 if(!IsCurrentModel())
890 vtkSmartPointer<vtkCellArray> aCellArray = vtkSmartPointer<vtkCellArray>::New();
891 vtkSmartPointer<vtkPolyData> triangulatedModel = vtkSmartPointer<vtkPolyData>::New();
892 triangulatedModel->SetPoints(
CurrentModel->GetPoints());
893 triangulatedModel->SetPolys(aCellArray);
896 vtkSmartPointer<vtkDelaunay2D> delaunay = vtkSmartPointer<vtkDelaunay2D>::New();
897 #if VTK_MAJOR_VERSION <= 5 899 delaunay->SetSource(triangulatedModel);
902 delaunay->SetSourceData(triangulatedModel);
904 if(VTKProgressUpdates->IsBeingObserved())
905 delaunay->AddObserver(vtkCommand::ProgressEvent, VTKProgressUpdates);
908 UpdateModelState(delaunay);
913 if(!IsCurrentModel())
916 vtkSmartPointer<vtkDelaunay3D> delaunay = vtkSmartPointer<vtkDelaunay3D>::New();
917 #if VTK_MAJOR_VERSION <= 5 922 if(VTKProgressUpdates->IsBeingObserved())
923 delaunay->AddObserver(vtkCommand::ProgressEvent, VTKProgressUpdates);
926 vtkSmartPointer<vtkGeometryFilter> region = vtkSmartPointer<vtkGeometryFilter>::New();
927 region->SetInputConnection(delaunay->GetOutputPort());
928 if(VTKProgressUpdates->IsBeingObserved())
929 region->AddObserver(vtkCommand::ProgressEvent, VTKProgressUpdates);
932 UpdateModelState(region);
937 if(!IsCurrentModel())
940 vtkSmartPointer<vtkVertexGlyphFilter> vertices = vtkSmartPointer<vtkVertexGlyphFilter>::New();
941 #if VTK_MAJOR_VERSION <= 5 946 if(VTKProgressUpdates->IsBeingObserved())
947 vertices->AddObserver(vtkCommand::ProgressEvent, VTKProgressUpdates);
950 UpdateModelState(vertices);
955 if(!IsCurrentModel())
958 vtkSmartPointer<vtkIdFilter> vertices = vtkSmartPointer<vtkIdFilter>::New();
959 #if VTK_MAJOR_VERSION <= 5 964 if(VTKProgressUpdates->IsBeingObserved())
965 vertices->AddObserver(vtkCommand::ProgressEvent, VTKProgressUpdates);
966 vertices->SetIdsArrayName(
"Point IDs");
967 vertices->PointIdsOn();
970 UpdateModelStateFromModel(vertices->GetPolyDataOutput());
975 if(!IsCurrentModel())
978 vtkSmartPointer<vtkGlyphSource2D> circle = vtkSmartPointer<vtkGlyphSource2D>::New();
979 if(glyphType == Circle)
980 circle->SetGlyphTypeToCircle();
981 else if(glyphType == Triangle)
982 circle->SetGlyphTypeToTriangle();
983 else if(glyphType == Square)
984 circle->SetGlyphTypeToSquare();
985 else if(glyphType == Diamond)
986 circle->SetGlyphTypeToDiamond();
988 circle->SetGlyphTypeToThickCross();
993 vtkSmartPointer<vtkGlyph3D> glyph = vtkSmartPointer<vtkGlyph3D>::New();
994 glyph->SetSourceConnection(circle->GetOutputPort());
995 #if VTK_MAJOR_VERSION <= 5 1000 if(VTKProgressUpdates->IsBeingObserved())
1001 glyph->AddObserver(vtkCommand::ProgressEvent, VTKProgressUpdates);
1004 UpdateModelState(glyph);
1009 if(!IsCurrentModel())
1012 vtkSmartPointer<vtkTubeFilter> tubes = vtkSmartPointer<vtkTubeFilter>::New();
1013 #if VTK_MAJOR_VERSION <= 5 1018 tubes->SetRadius(0.02);
1019 tubes->SetNumberOfSides(3);
1020 if(VTKProgressUpdates->IsBeingObserved())
1021 tubes->AddObserver(vtkCommand::ProgressEvent, VTKProgressUpdates);
1024 UpdateModelState(tubes);
1029 if(!IsCurrentModel())
1032 vtkSmartPointer<vtkSphereSource> sphere = vtkSmartPointer<vtkSphereSource>::New();
1034 vtkSmartPointer<vtkGlyph3D> glyphs = vtkSmartPointer<vtkGlyph3D>::New();
1035 glyphs->SetSourceConnection(sphere->GetOutputPort());
1036 #if VTK_MAJOR_VERSION <= 5 1041 glyphs->SetScaleModeToDataScalingOff();
1042 glyphs->SetScaleFactor(newScale);
1043 if(VTKProgressUpdates->IsBeingObserved())
1044 glyphs->AddObserver(vtkCommand::ProgressEvent, VTKProgressUpdates);
1047 UpdateModelState(glyphs);
1052 if(!IsCurrentModel())
1055 vtkSmartPointer<vtkPolyDataPointSampler> pointSampler = vtkSmartPointer<vtkPolyDataPointSampler>::New();
1056 pointSampler->SetDistance(distance);
1057 #if VTK_MAJOR_VERSION <= 5 1062 pointSampler->GenerateVertexPointsOn();
1063 pointSampler->GenerateVerticesOn();
1064 if(VTKProgressUpdates->IsBeingObserved())
1065 pointSampler->AddObserver(vtkCommand::ProgressEvent, VTKProgressUpdates);
1066 pointSampler->Update();
1068 UpdateModelState(pointSampler);
1073 if(!IsCurrentModel())
1076 vtkSmartPointer<vtkArrowSource> arrows = vtkSmartPointer<vtkArrowSource>::New();
1077 arrows->SetShaftResolution(3);
1078 arrows->SetTipResolution(3);
1080 vtkSmartPointer<vtkGlyph3D> glyphs = vtkSmartPointer<vtkGlyph3D>::New();
1083 glyphs->SetVectorModeToUseNormal();
1084 glyphs->SetScaleModeToScaleByScalar();
1088 glyphs->SetVectorModeToUseVector();
1089 glyphs->SetScaleModeToScaleByVector();
1090 glyphs->SetColorModeToColorByScalar();
1092 glyphs->SetSourceConnection(arrows->GetOutputPort());
1093 #if VTK_MAJOR_VERSION <= 5 1100 glyphs->SetScaleFactor(newScale);
1101 if(VTKProgressUpdates->IsBeingObserved())
1102 glyphs->AddObserver(vtkCommand::ProgressEvent, VTKProgressUpdates);
1105 UpdateModelState(glyphs);
1110 if(!IsCurrentModel())
1113 vtkSmartPointer<vtkSphereSource> sphere = vtkSmartPointer<vtkSphereSource>::New();
1114 sphere->SetThetaResolution(4);
1115 sphere->SetPhiResolution(4);
1117 vtkSmartPointer<vtkTensorGlyph> ellipsoids = vtkSmartPointer<vtkTensorGlyph>::New();
1118 #if VTK_MAJOR_VERSION <= 5 1120 ellipsoids->SetSource(sphere->GetOutput());
1123 ellipsoids->SetSourceData(sphere->GetOutput());
1125 ellipsoids->ScalingOn();
1126 ellipsoids->ClampScalingOn();
1128 ellipsoids->SetScaleFactor(newScale);
1129 ellipsoids->SetColorModeToScalars();
1130 if(VTKProgressUpdates->IsBeingObserved())
1131 ellipsoids->AddObserver(vtkCommand::ProgressEvent, VTKProgressUpdates);
1132 ellipsoids->Update();
1134 UpdateModelState(ellipsoids);
1139 if(!IsCurrentModel())
1142 vtkSmartPointer<vtkHedgeHog> hedgeHog = vtkSmartPointer<vtkHedgeHog>::New();
1143 hedgeHog->SetVectorModeToUseVector();
1144 #if VTK_MAJOR_VERSION <= 5 1150 hedgeHog->SetScaleFactor(newScale);
1151 if(VTKProgressUpdates->IsBeingObserved())
1152 hedgeHog->AddObserver(vtkCommand::ProgressEvent, VTKProgressUpdates);
1155 UpdateModelState(hedgeHog);
1160 if(!IsCurrentModel())
1164 vtkSmartPointer<vtkPolyDataNormals> surfaceNormals = vtkSmartPointer<vtkPolyDataNormals>::New();
1165 surfaceNormals->ComputeCellNormalsOn();
1166 if(pointNormals == 0)
1168 surfaceNormals->ComputePointNormalsOn();
1169 surfaceNormals->ComputeCellNormalsOff();
1171 else if(pointNormals == 1)
1173 surfaceNormals->ComputePointNormalsOff();
1174 surfaceNormals->ComputeCellNormalsOn();
1178 surfaceNormals->ComputePointNormalsOn();
1179 surfaceNormals->ComputeCellNormalsOn();
1181 surfaceNormals->SplittingOff();
1182 surfaceNormals->ConsistencyOn();
1184 #if VTK_MAJOR_VERSION <= 5 1189 surfaceNormals->SetFeatureAngle(37);
1190 if(VTKProgressUpdates->IsBeingObserved())
1191 surfaceNormals->AddObserver(vtkCommand::ProgressEvent, VTKProgressUpdates);
1192 surfaceNormals->Update();
1194 CurrentModel->GetPointData()->SetNormals( surfaceNormals->GetOutput()->GetPointData()->GetNormals() );
1199 if(!IsCurrentModel())
1202 vtkSmartPointer<vtkTable> inputData = vtkSmartPointer<vtkTable>::New();
1203 for (
int c = 0; c < 3; ++c )
1205 std::stringstream colName;
1206 colName <<
"coord " << c;
1207 vtkSmartPointer<vtkDoubleArray> doubleArray = vtkSmartPointer<vtkDoubleArray>::New();
1208 doubleArray->SetNumberOfComponents(1);
1209 doubleArray->SetName( colName.str().c_str() );
1210 doubleArray->SetNumberOfTuples(
CurrentModel->GetNumberOfPoints());
1212 for (
int r = 0; r <
CurrentModel->GetNumberOfPoints(); ++ r )
1217 doubleArray->SetValue( r, p[c] );
1220 inputData->AddColumn( doubleArray );
1223 vtkSmartPointer<vtkKMeansStatistics> kMeansStatistics = vtkSmartPointer<vtkKMeansStatistics>::New();
1224 #if VTK_MAJOR_VERSION <= 5 1225 kMeansStatistics->SetInput( vtkStatisticsAlgorithm::INPUT_DATA, inputData );
1227 kMeansStatistics->SetInputData( vtkStatisticsAlgorithm::INPUT_DATA, inputData );
1229 kMeansStatistics->SetColumnStatus( inputData->GetColumnName( 0 ) , 1 );
1230 kMeansStatistics->SetColumnStatus( inputData->GetColumnName( 1 ) , 1 );
1231 kMeansStatistics->SetColumnStatus( inputData->GetColumnName( 2 ) , 1 );
1233 kMeansStatistics->RequestSelectedColumns();
1234 kMeansStatistics->SetAssessOption(
true );
1235 kMeansStatistics->SetDefaultNumberOfClusters( numberOfClusters );
1236 if(VTKProgressUpdates->IsBeingObserved())
1237 kMeansStatistics->AddObserver(vtkCommand::ProgressEvent, VTKProgressUpdates);
1238 kMeansStatistics->Update();
1241 const float scaling = 256.0/numberOfClusters;
1242 vtkSmartPointer<vtkFloatArray> clusterArray = vtkSmartPointer<vtkFloatArray>::New();
1243 clusterArray->SetNumberOfComponents(1);
1244 clusterArray->SetName(
"Cluster ID" );
1245 for (
unsigned int r = 0; r < kMeansStatistics->GetOutput()->GetNumberOfRows(); r++)
1247 vtkVariant v = kMeansStatistics->GetOutput()->GetValue(r,kMeansStatistics->GetOutput()->GetNumberOfColumns() - 1);
1249 clusterArray->InsertNextValue(scaling*(v.ToInt()+1));
1251 CurrentModel->GetPointData()->SetScalars(clusterArray);
1256 if(!IsCurrentModel())
1259 vtkSmartPointer<vtkQuantizePolyDataPoints> quantizeFilter = vtkSmartPointer<vtkQuantizePolyDataPoints>::New();
1260 #if VTK_MAJOR_VERSION <= 5 1265 quantizeFilter->SetQFactor(quantiseFactor);
1266 if(VTKProgressUpdates->IsBeingObserved())
1267 quantizeFilter->AddObserver(vtkCommand::ProgressEvent, VTKProgressUpdates);
1268 quantizeFilter->Update();
1270 UpdateModelState(quantizeFilter);
1275 if(!IsCurrentModel())
1279 vtkSmartPointer<vtkFeatureEdges> boundaryEdges = vtkSmartPointer<vtkFeatureEdges>::New();
1280 #if VTK_MAJOR_VERSION <= 5 1285 boundaryEdges->BoundaryEdgesOn();
1286 boundaryEdges->FeatureEdgesOff();
1287 boundaryEdges->NonManifoldEdgesOff();
1288 boundaryEdges->ManifoldEdgesOff();
1289 if(VTKProgressUpdates->IsBeingObserved())
1290 boundaryEdges->AddObserver(vtkCommand::ProgressEvent, VTKProgressUpdates);
1293 vtkSmartPointer<vtkStripper> boundaryStrips = vtkSmartPointer<vtkStripper>::New();
1294 boundaryStrips->SetInputConnection(boundaryEdges->GetOutputPort());
1295 if(VTKProgressUpdates->IsBeingObserved())
1296 boundaryStrips->AddObserver(vtkCommand::ProgressEvent, VTKProgressUpdates);
1297 boundaryStrips->Update();
1300 vtkSmartPointer<vtkPolyData> boundaryPoly = vtkSmartPointer<vtkPolyData>::New();
1301 boundaryPoly->SetPoints(boundaryStrips->GetOutput()->GetPoints());
1302 boundaryPoly->SetPolys(boundaryStrips->GetOutput()->GetLines());
1309 if(!IsCurrentModel())
1313 vtkSmartPointer<vtkConnectivityFilter> connectivityFilter = vtkSmartPointer<vtkConnectivityFilter>::New();
1314 #if VTK_MAJOR_VERSION <= 5 1319 connectivityFilter->SetExtractionModeToAllRegions();
1320 connectivityFilter->ColorRegionsOn();
1321 if(VTKProgressUpdates->IsBeingObserved())
1322 connectivityFilter->AddObserver(vtkCommand::ProgressEvent, VTKProgressUpdates);
1324 vtkSmartPointer<vtkGeometryFilter> region = vtkSmartPointer<vtkGeometryFilter>::New();
1325 region->SetInputConnection(connectivityFilter->GetOutputPort());
1326 if(VTKProgressUpdates->IsBeingObserved())
1327 region->AddObserver(vtkCommand::ProgressEvent, VTKProgressUpdates);
1330 UpdateModelState(region);
1335 if(!IsCurrentModel())
1339 vtkSmartPointer<vtkSimpleElevationFilter> elevationFilter = vtkSmartPointer<vtkSimpleElevationFilter>::New();
1340 #if VTK_MAJOR_VERSION <= 5 1345 elevationFilter->SetVector(x, y, z);
1346 if(VTKProgressUpdates->IsBeingObserved())
1347 elevationFilter->AddObserver(vtkCommand::ProgressEvent, VTKProgressUpdates);
1348 elevationFilter->Update();
1350 UpdateModelStateFromModel(elevationFilter->GetPolyDataOutput());
1355 if(!IsCurrentModel())
1362 vtkSmartPointer<vtkElevationFilter> elevationFilter = vtkSmartPointer<vtkElevationFilter>::New();
1363 #if VTK_MAJOR_VERSION <= 5 1368 elevationFilter->SetLowPoint(bounds[0], bounds[2], bounds[4]);
1369 elevationFilter->SetHighPoint(bounds[0], bounds[2], bounds[5]);
1370 if(VTKProgressUpdates->IsBeingObserved())
1371 elevationFilter->AddObserver(vtkCommand::ProgressEvent, VTKProgressUpdates);
1372 elevationFilter->Update();
1374 UpdateModelStateFromModel(elevationFilter->GetPolyDataOutput());
1461 vtkSmartPointer<vtkAppendPolyData> appendPolyData = vtkSmartPointer<vtkAppendPolyData>::New();
1462 #if VTK_MAJOR_VERSION <= 5 1465 appendPolyData->AddInput(model);
1469 appendPolyData->AddInputData(model);
1471 appendPolyData->Update();
1476 void Model::Scale(vtkSmartPointer<vtkPolyData> model,
const coordinateType scale,
const bool useCentroid)
1478 vtkSmartPointer<vtkPoints> points = model->GetPoints();
1479 const size_t numberOfPoints = model->GetNumberOfPoints();
1481 coordinate centroid(0.0);
1483 coordinate centroid =
new coordinateType[3];
1489 for(
size_t j = 0; j < numberOfPoints; j ++)
1492 coordinate point(points->GetPoint(j));
1502 points->SetPoint(j, point.data_block());
1504 coordinateType point[3];
1505 points->GetPoint(j, point);
1509 point[0] -= centroid[0];
1510 point[1] -= centroid[1];
1511 point[2] -= centroid[2];
1520 point[0] += centroid[0];
1521 point[1] += centroid[1];
1522 point[2] += centroid[2];
1525 points->SetPoint(j, point);
1530 void Model::ScalarDifference(vtkSmartPointer<vtkPolyData> model1, vtkSmartPointer<vtkPolyData> model2, vtkSmartPointer<vtkPolyData> result)
1532 const size_t numberOfPoints = model1->GetNumberOfPoints();
1534 for(
size_t j = 0; j < numberOfPoints; j ++)
1536 double scalar1 = model1->GetPointData()->GetScalars()->GetTuple1(j);
1537 double scalar2 = model2->GetPointData()->GetScalars()->GetTuple1(j);
1538 double resultant = result->GetPointData()->GetScalars()->GetTuple1(j);
1540 resultant += scalar1 - scalar2;
1542 result->GetPointData()->GetScalars()->SetTuple1(j, resultant);
1546 void Model::ThresholdScalars(vtkSmartPointer<vtkPolyData> model,
const coordinateType aboveVal,
const coordinateType belowVal,
const coordinateType outsideVal)
1551 void Model::BinaryThresholdScalars(vtkSmartPointer<vtkPolyData> model,
const coordinateType aboveVal,
const coordinateType belowVal,
const coordinateType insideVal,
const coordinateType outsideVal)
1553 if(!model->GetPointData()->GetScalars())
1556 vtkSmartPointer<vtkDataArray> scalars = model->GetPointData()->GetScalars();
1557 for(vtkIdType j = 0; j < scalars->GetNumberOfTuples(); j ++)
1559 coordinateType scalar = scalars->GetTuple1(j);
1560 coordinateType value = 0.0;
1562 if(insideVal == outsideVal || vtkMath::IsNan(insideVal))
1567 if(scalar < belowVal || scalar > aboveVal)
1568 scalars->SetTuple1(j, outsideVal);
1570 scalars->SetTuple1(j, value);
1576 if(!model1->GetPointData()->GetScalars() || !model1->GetPointData()->GetScalars())
1579 vtkSmartPointer<vtkDataArray> scalars1 = model1->GetPointData()->GetScalars();
1580 vtkSmartPointer<vtkDataArray> scalars2 = model2->GetPointData()->GetScalars();
1581 for(vtkIdType j = 0; j < scalars1->GetNumberOfTuples(); j ++)
1583 coordinateType scalar1 = scalars1->GetTuple1(j);
1584 coordinateType scalar2 = scalars2->GetTuple1(j);
1585 coordinateType value = 0.0;
1590 scalars1->SetTuple1(j, value);
1594 vtkSmartPointer<vtkMatrix4x4>
Model::ProcrustesAlign(vtkSmartPointer<vtkPolyData> source, vtkSmartPointer<vtkPolyData> target,
bool rigid)
1596 if(source->GetNumberOfPoints() != target->GetNumberOfPoints())
1600 vtkSmartPointer<vtkLandmarkTransform> landmarkTransform = vtkSmartPointer<vtkLandmarkTransform>::New();
1601 landmarkTransform->SetSourceLandmarks(source->GetPoints());
1602 landmarkTransform->SetTargetLandmarks(target->GetPoints());
1603 landmarkTransform->SetModeToSimilarity();
1605 landmarkTransform->SetModeToRigidBody();
1606 landmarkTransform->Update();
1607 for(vtkIdType v = 0; v < source->GetNumberOfPoints(); v ++)
1609 landmarkTransform->InternalTransformPoint(source->GetPoint(v), outPoint);
1610 source->GetPoints()->SetPoint(v, outPoint);
1613 vtkSmartPointer<vtkMatrix4x4> currentTransformMatrix = vtkSmartPointer<vtkMatrix4x4>::New();
1614 currentTransformMatrix->DeepCopy(landmarkTransform->GetMatrix());
1616 return currentTransformMatrix;
1622 const size_t n = collection->GetNumberOfItems();
1624 collection->InitTraversal();
1625 for(
size_t j = 0; j < n; j ++)
1626 Append(collection->GetNextItem());
1631 const size_t n = collection->GetNumberOfItems();
1633 collection->InitTraversal();
1634 for(
size_t j = 0; j < n; j ++)
1635 Scale(collection->GetNextItem(), scale);
1640 const size_t n = collection->GetNumberOfItems();
1643 collection->InitTraversal();
1644 for(
size_t j = 0; j < n; j ++)
1646 vtkSmartPointer<vtkPolyData> mesh = collection->GetNextItem();
1649 mesh->DeepCopy(
Result());
1657 const size_t n = collection->GetNumberOfItems();
1660 collection->InitTraversal();
1661 for(
size_t j = 0; j < n; j ++)
1663 vtkSmartPointer<vtkPolyData> mesh = collection->GetNextItem();
1666 mesh->DeepCopy(
Result());
1672 void Model::FlipCollection(vtkSmartPointer<vtkPolyDataCollection> collection,
const bool xAxis,
const bool yAxis,
const bool zAxis)
1674 const size_t n = collection->GetNumberOfItems();
1677 collection->InitTraversal();
1678 for(
size_t j = 0; j < n; j ++)
1680 vtkSmartPointer<vtkPolyData> mesh = collection->GetNextItem();
1682 Flip(xAxis, yAxis, zAxis);
1683 mesh->DeepCopy(
Result());
1691 const size_t n = collection->GetNumberOfItems();
1694 collection->InitTraversal();
1695 for(
size_t j = 0; j < n; j ++)
1697 vtkSmartPointer<vtkPolyData> mesh = collection->GetNextItem();
1700 mesh->DeepCopy(
Result());
1706 void Model::SplitCollection(vtkSmartPointer<vtkPolyDataCollection> collection, vtkSmartPointer<vtkPolyDataCollection> components, std::vector< vtkSmartPointer<vtkPolyDataCollection> > &splitCollections)
1708 const size_t n = collection->GetNumberOfItems();
1709 const size_t m = components->GetNumberOfItems();
1711 collection->InitTraversal();
1712 for(
size_t j = 0; j < n; j ++)
1714 vtkSmartPointer<vtkPolyDataCollection> splitCollection = vtkSmartPointer<vtkPolyDataCollection>::New();
1715 vtkSmartPointer<vtkPolyData> hybridSurface = collection->GetNextItem();
1716 vtkSmartPointer<vtkFloatArray> hybridScalars = vtkFloatArray::SafeDownCast(hybridSurface->GetPointData()->GetScalars());
1717 size_t accumulatedPoints = 0;
1719 components->InitTraversal();
1720 for(
size_t k = 0; k < m; k ++)
1722 vtkSmartPointer<vtkPolyData> splitResult = vtkSmartPointer<vtkPolyData>::New();
1723 vtkSmartPointer<vtkFloatArray> scalars = vtkSmartPointer<vtkFloatArray>::New();
1724 vtkSmartPointer<vtkPolyData> component = components->GetNextItem();
1725 const size_t numberOfPoints = component->GetNumberOfPoints();
1729 scalars->SetNumberOfComponents(hybridScalars->GetNumberOfComponents());
1730 scalars->SetNumberOfTuples(numberOfPoints);
1734 splitResult->DeepCopy(component);
1735 for(
size_t l = 0; l < numberOfPoints; l ++)
1737 splitResult->GetPoints()->SetPoint(l, hybridSurface->GetPoint(l + accumulatedPoints));
1739 scalars->SetTuple(l, hybridScalars->GetTuple(l + accumulatedPoints));
1743 splitResult->GetPointData()->SetScalars(scalars);
1745 splitCollection->AddItem(splitResult);
1746 accumulatedPoints += numberOfPoints;
1749 splitCollections.push_back(splitCollection);
1755 const size_t n = collection->GetNumberOfItems();
1757 collection->InitTraversal();
1758 vtkSmartPointer<vtkPolyData> surface1 = collection->GetNextItem();
1763 for(
size_t j = 1; j < n; j ++)
1765 vtkSmartPointer<vtkPolyData> surface2 = collection->GetNextItem();
1773 const size_t n = collection->GetNumberOfItems();
1775 collection->InitTraversal();
1776 for(
size_t j = 1; j < n; j ++)
1778 vtkSmartPointer<vtkPolyData> surface = collection->GetNextItem();
1784 void Model::ClipCollection(vtkSmartPointer<vtkPolyDataCollection> collection,
const coordinateType aboveVal,
const coordinateType belowVal)
1786 const size_t n = collection->GetNumberOfItems();
1788 collection->InitTraversal();
1789 for(
size_t j = 0; j < n; j ++)
1791 vtkSmartPointer<vtkPolyData> mesh = collection->GetNextItem();
1793 Clip(aboveVal, belowVal);
1794 mesh->DeepCopy(
Result());
1800 void Model::ScalarDifferenceCollection(vtkSmartPointer<vtkPolyDataCollection> collection1, vtkSmartPointer<vtkPolyDataCollection> collection2, vtkSmartPointer<vtkPolyDataCollection> &results)
1802 const size_t n = collection1->GetNumberOfItems();
1804 if(collection1->GetNumberOfItems() != collection2->GetNumberOfItems())
1810 collection1->InitTraversal();
1811 collection2->InitTraversal();
1812 for(
size_t j = 0; j < n; j ++)
1814 vtkSmartPointer<vtkPolyData> surface1 = collection1->GetNextItem();
1815 vtkSmartPointer<vtkPolyData> surface2 = collection2->GetNextItem();
1817 vtkPolyData *result = vtkPolyData::New();
1818 result->DeepCopy(surface1);
1819 vtkSmartPointer<milxArrayType> scalars = vtkSmartPointer<milxArrayType>::New();
1820 scalars->SetNumberOfTuples(result->GetNumberOfPoints());
1821 scalars->SetNumberOfComponents(1);
1822 scalars->FillComponent(0, 0.0);
1823 result->GetPointData()->SetScalars(scalars);
1827 results->AddItem(result);
1833 const size_t s = collection->GetNumberOfItems();
1835 collection->InitTraversal();
1836 vtkSmartPointer<vtkPolyData> firstSurface = collection->GetNextItem();
1837 const size_t n = firstSurface->GetNumberOfPoints();
1839 milxArrayType *minScalars = milxArrayType::New();
1840 minScalars->SetName(
"Minimum per Vertex");
1841 minScalars->SetNumberOfTuples(n);
1842 minScalars->SetNumberOfComponents(1);
1843 minScalars->FillComponent(0, minScalars->GetDataTypeMax());
1844 milxArrayType *maxScalars = milxArrayType::New();
1845 maxScalars->SetName(
"Maximum per Vertex");
1846 maxScalars->SetNumberOfTuples(n);
1847 maxScalars->SetNumberOfComponents(1);
1848 maxScalars->FillComponent(0, maxScalars->GetDataTypeMin());
1849 milxArrayType *meanScalars = milxArrayType::New();
1850 meanScalars->SetName(
"Mean per Vertex");
1851 meanScalars->SetNumberOfTuples(n);
1852 meanScalars->SetNumberOfComponents(1);
1853 meanScalars->FillComponent(0, 0.0);
1854 milxArrayType *varScalars = milxArrayType::New();
1855 varScalars->SetName(
"Variance per Vertex");
1856 varScalars->SetNumberOfTuples(n);
1857 varScalars->SetNumberOfComponents(1);
1858 varScalars->FillComponent(0, 0.0);
1861 collection->InitTraversal();
1862 for(
size_t j = 0; j < s; j ++)
1864 vtkSmartPointer<vtkPolyData> mesh = collection->GetNextItem();
1866 if(!mesh->GetPointData()->GetScalars())
1870 vtkSmartPointer<vtkDataArray> scalars = mesh->GetPointData()->GetScalars();
1872 for(
size_t k = 0; k < n; k ++)
1874 if(scalars->GetTuple1(k) < minScalars->GetTuple1(k))
1875 minScalars->SetTuple1(k, scalars->GetTuple1(k));
1876 if(scalars->GetTuple1(k) > maxScalars->GetTuple1(k))
1877 maxScalars->SetTuple1(k, scalars->GetTuple1(k));
1879 meanScalars->SetTuple1( k, meanScalars->GetTuple1(k) + scalars->GetTuple1(k) );
1886 for(
size_t k = 0; k < n; k ++)
1887 meanScalars->SetTuple1( k, meanScalars->GetTuple1(k)/count );
1889 collection->InitTraversal();
1890 for(
size_t j = 0; j < s; j ++)
1892 vtkSmartPointer<vtkPolyData> mesh = collection->GetNextItem();
1894 if(!mesh->GetPointData()->GetScalars())
1898 vtkSmartPointer<vtkDataArray> scalars = mesh->GetPointData()->GetScalars();
1900 for(
size_t k = 0; k < n; k ++)
1902 const coordinateType diffValue = scalars->GetTuple1(k) - meanScalars->GetTuple1(k);
1903 varScalars->SetTuple1( k, varScalars->GetTuple1(k) + (diffValue*diffValue)/count );
1914 CurrentModel->GetPointData()->SetActiveScalars(
"Mean per Vertex");
1919 const size_t n = collection->GetNumberOfItems();
1921 collection->InitTraversal();
1922 for(
size_t j = 0; j < n; j ++)
1924 vtkSmartPointer<vtkPolyData> surface = collection->GetNextItem();
1932 const size_t n = collection->GetNumberOfItems();
1934 collection->InitTraversal();
1935 vtkSmartPointer<vtkPolyData> templateSurface = collection->GetNextItem();
1936 for(
size_t j = 1; j < n; j ++)
1938 vtkSmartPointer<vtkPolyData> surface = collection->GetNextItem();
1942 surface->GetPointData()->SetScalars(templateSurface->GetPointData()->GetScalars());
1948 const size_t n = collection->GetNumberOfItems();
1952 collection->InitTraversal();
1955 vtkSmartPointer<vtkPolyData> surface1 = collection->GetNextItem();
1961 vtkSmartPointer<vtkPolyData> surface2 = collection->GetNextItem();
1972 const int n = collection->GetNumberOfItems();
1974 collection->InitTraversal();
1977 vtkSmartPointer<vtkProcrustesAlignmentFilter> procrustes = vtkSmartPointer<vtkProcrustesAlignmentFilter>::New();
1978 #if VTK_MAJOR_VERSION <=5 1979 procrustes->SetNumberOfInputs(n);
1983 procrustes->GetLandmarkTransform()->SetModeToRigidBody();
1984 procrustes->StartFromCentroidOn();
1987 procrustes->GetLandmarkTransform()->SetModeToSimilarity();
1992 vtkSmartPointer<milxArrayType> meanScalars = vtkSmartPointer<milxArrayType>::New();
1993 meanScalars->SetNumberOfComponents(1);
1995 #if VTK_MAJOR_VERSION <=5 1996 for(
int j = 0; j < n; j ++)
1997 procrustes->SetInput(j, collection->GetNextItem());
1999 vtkSmartPointer<vtkMultiBlockDataGroupFilter> group = vtkSmartPointer<vtkMultiBlockDataGroupFilter>::New();
2000 for(
int j = 0; j < n; j ++)
2001 group->AddInputData(collection->GetNextItem());
2002 procrustes->SetInputConnection(group->GetOutputPort());
2005 int numberOfPoints = 0;
2008 #if VTK_MAJOR_VERSION <=5 2009 numberOfPoints = procrustes->GetInput(0)->GetNumberOfPoints();
2011 numberOfPoints = vtkPointSet::SafeDownCast(procrustes->GetOutput()->GetBlock(0))->
GetNumberOfPoints();
2013 meanScalars->SetNumberOfTuples(numberOfPoints);
2014 meanScalars->FillComponent(0, 0.0);
2016 procrustes->Update();
2018 vtkSmartPointer<vtkPolyDataCollection> alignedCollection = vtkSmartPointer<vtkPolyDataCollection>::New();
2019 collection->InitTraversal();
2020 for(
int j = 0; j < n; j ++)
2022 vtkPolyData *aligned = vtkPolyData::New();
2023 aligned->DeepCopy(collection->GetNextItem());
2024 #if VTK_MAJOR_VERSION <=5 2025 aligned->SetPoints(procrustes->GetOutput(j)->GetPoints());
2027 aligned->SetPoints( vtkPointSet::SafeDownCast(procrustes->GetOutput()->GetBlock(j))->
GetPoints() );
2030 if(aligned->GetPointData()->GetScalars())
2032 for(
int k = 0; k < numberOfPoints; k ++)
2034 const double scalar = aligned->GetPointData()->GetScalars()->GetTuple1(k);
2035 double resultant = meanScalars->GetTuple1(k);
2037 resultant += scalar;
2039 meanScalars->SetTuple1(k, resultant);
2046 alignedCollection->AddItem(aligned);
2050 for(
int k = 0; k < numberOfPoints; k ++)
2052 double resultant = meanScalars->GetTuple1(k);
2056 meanScalars->SetTuple1(k, resultant);
2061 return alignedCollection;
2065 vtkSmartPointer<vtkTransformCollection> tCollection)
2067 const int n = collection->GetNumberOfItems();
2068 vtkSmartPointer<vtkPolyDataCollection> alignedCollection = vtkSmartPointer<vtkPolyDataCollection>::New();
2071 vtkPolyData *last =
static_cast<vtkPolyData *
>(collection->GetItemAsObject(n-1));
2073 collection->InitTraversal();
2074 for(
int j = 0; j < n-1; j ++)
2076 vtkPolyData *aligned = collection->GetNextItem();
2082 vtkSmartPointer<vtkPolyData> result = vtkSmartPointer<vtkPolyData>::New();
2083 result->DeepCopy(
Result());
2084 alignedCollection->AddItem(result);
2086 if (tCollection.GetPointer() != 0) {
2087 vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New();
2089 tCollection->AddItem(transform);
2094 return alignedCollection;
void PrintDebug(const std::string msg)
Displays a generic msg to standard error with carriage return if in Debug mode.
vtkSmartPointer< vtkPolyData > CurrentModel
Holds the current model in the pipeline.
static Type Centroid(const vnl_vector< Type > &data)
Compute the centroid (or the mean) of a data vector.
static Type MeanSquaredError(vtkPoints *sourcePoints, vtkPoints *targetPoints)
Compute the MSE of the given points sets.
void ScalarStatisticsCollection(vtkSmartPointer< vtkPolyDataCollection > collection)
Computes the statistics (min, max, variance etc.) of the scalars over the collection assuming the mes...
void DelaunayTriangulation()
Compute the Delaunay 3D triangluation of the points in the mesh.
void GenerateVertexScalars()
Generate vertex scalars for display from point data. This colours the mesh by point ids...
static void ThresholdScalars(vtkSmartPointer< vtkPolyData > model, const coordinateType aboveVal, const coordinateType belowVal, const coordinateType outsideVal)
Thresholds scalar values of mesh in place.
void GenerateCappedBoundaries()
Generate capped boundaries for open meshes. This closes off open ends of a mesh.
void ConcatenateCollection(vtkSmartPointer< vtkPolyDataCollection > collection)
Concatenates all the models in the collection together into one model.
void GenerateHedgehog(const double newScale=0.0)
Generate a line field for vectors present (as an array) in the mesh at given scaling.
void RemoveScalars()
Removes all the scalars from the current model. Same as ClearScalars()
void GenerateVertices()
Generate (only) vertices for display from point data. Good for when only points in mesh...
void Flip(const bool xAxis, const bool yAxis, const bool zAxis)
Flip the mesh along the selected axes.
void GenerateTensorField(const double newScale=0.0)
Generate tensor field for tensors present (as an array) in the mesh at given scaling.
void GenerateRegions()
Generate connected regions for the mesh labelled by scalar values.
bool InternalInPlaceOperation
Used by the collection members to assign via pointers rather than deep copys.
void Mask(vtkSmartPointer< vtkPolyData > maskMesh)
Mask the scalars on the mesh based on values of maskMesh being >= 1.
void ScaleCollection(vtkSmartPointer< vtkPolyDataCollection > collection, const coordinateType scale)
Scales the coordinates of each point in all the models in the collection.
static void ScalarDifference(vtkSmartPointer< vtkPolyData > model1, vtkSmartPointer< vtkPolyData > model2, vtkSmartPointer< vtkPolyData > result)
Calculates differences within scalars of two meshes assuming the meshes have the same number of point...
vtkSmartPointer< vtkDataArray > GetScalars()
Returns the active scalars of the model.
void SetPolys(vtkSmartPointer< vtkCellArray > modelPolys)
Assign polygons to the model via the array given.
void PrintError(const std::string msg)
Displays a generic msg to standard error with carriage return.
void SetGraph(vtkSmartPointer< vtkMutableUndirectedGraph > graph)
Converts a graph to polydata/mesh ready for display.
void GenerateSampledPoints(const double distance)
Generate sampled points (only points) for the mesh at given spacing on triangles. ...
void DecimateCollection(vtkSmartPointer< vtkPolyDataCollection > collection, const coordinateType factor)
Decimates all points in all the models in the collection using the Quadric algorithm algorithm...
void DelaunayGraph3D()
Compute the Delaunay 3D graph of the points in the mesh.
void RemoveArrays()
Removes all the arrays from the current model. Same as ClearArrayss()
void SplitCollection(vtkSmartPointer< vtkPolyDataCollection > collection, vtkSmartPointer< vtkPolyDataCollection > components, std::vector< vtkSmartPointer< vtkPolyDataCollection > > &splitCollections)
Splits each of the models in the collection into a collection of models.
void Delaunay2DTriangulation()
Compute the Delaunay 2D triangluation of the points in the mesh.
vtkSmartPointer< vtkPolyData > & Result()
Returns the current model, i.e. the result of the latest operation.
vtkSmartPointer< vtkPolyDataCollection > ProcrustesAlignCollection(vtkSmartPointer< vtkPolyDataCollection > collection, bool rigid=false)
Aligns the collection to the mean mesh (computed internally) of the collection assuming the meshes ha...
void FillScalars(const coordinateType value)
Sets all the scalars of the current model to value.
static vtkSmartPointer< vtkMatrix4x4 > ProcrustesAlign(vtkSmartPointer< vtkPolyData > source, vtkSmartPointer< vtkPolyData > target, bool rigid=false)
Aligns the source mesh to target mesh assuming the meshes have the same number of points and correspo...
void SmoothCollection(vtkSmartPointer< vtkPolyDataCollection > collection, const size_t iterations)
Smoothes all points in all the models in the collection using the Windowed Sinc algorithm.
void SetPoints(vtkSmartPointer< vtkPoints > modelPoints)
Assign points to the model.
static void MaskScalars(vtkSmartPointer< vtkPolyData > model1, vtkSmartPointer< vtkPolyData > model2)
Masks the scalars in model1 with scalars in model2. Only values corresponding to >= 1 in model2 are k...
void Decimate(const float reduceFactor)
Decimate the mesh (in terms of points) using the Decimate PRO. Generally use QuadricDecimate() instea...
void SetVectors(vtkSmartPointer< vtkDataArray > modelVectors)
Sets the vector field of the mesh (vectors per vertex of the surface)
static void ClearScalars(vtkSmartPointer< vtkPolyData > &mesh)
Removes all the scalars from the current model.
void Append(vtkSmartPointer< vtkPolyData > model)
Appends the model provided to the member into the current model.
vtkSmartPointer< vtkPolyData > PreviousModel
Holds the previous model in the pipeline.
void GenerateVerticesAs2DGlyphs(const GlyphType glyphType)
Generate (only) vertices (as 2D glyphs like crosses etc.) for display from point data. Good for when only points in mesh.
void Threshold(const coordinateType belowVal, const coordinateType aboveVal, const coordinateType outsideVal)
Threshold the scalars on the mesh based on a levels provided.
void QuadricDecimate(const float reduceFactor)
Decimate the mesh (in terms of points) using the Quadric algorithm.
void WindowedSincSmoothing(const int iterations, const float passBand=0.1)
Smooth the mesh (in terms of points) using the Taubin (1995) optimal filter.
void Curvature(const bool meanCurvature=true)
Compute the curvature (using Laplace-Beltrami operator) of the mesh.
void SetInput(vtkSmartPointer< vtkPolyData > model)
Assigns the input model to class.
Model()
Standard constructor.
void LaplacianSmoothing(const int iterations)
Smooth the mesh (in terms of points) using the Laplacian algorithm. It is unstable, use WindowedSincSmoothing() instead unless massive non-edge preserving smoothing is required.
void ScalarThresholdCollection(vtkSmartPointer< vtkPolyDataCollection > collection, const coordinateType aboveVal, const coordinateType belowVal)
Computes the Threshold of scalar values of meshes in place over the collection wrt the first mesh ass...
void SetTransform(vtkSmartPointer< vtkAbstractTransform > newTransform)
Transforms the model by given transform.
void ResetScalars()
Resets the scalars to zero of the current model.
vtkSmartPointer< vtkTransform > CurrentTransform
transform applied to model
void LandmarkBasedRegistration(vtkSmartPointer< vtkPolyData > fixedMesh, const bool similarity=false)
Computes the landmark transform registration of the current mesh to the one provided. Requires point correspondence and same number of points.
static void ClearArrays(vtkSmartPointer< vtkPolyData > &mesh)
Removes all the arrays from the current model.
void Clean()
Removes duplicate points etc. from model.
std::string NumberToString(double num, unsigned zeroPad=0)
Number to string converter.
void Gradient()
Compute the gradient (using Laplace-Beltrami operator) of the scalars on the mesh.
vtkSmartPointer< vtkImageData > Voxelise(const unsigned char insideValue, double *spacing, double *bounds=NULL, const size_t padVoxels=1)
static Type CentroidSize(const vnl_matrix< Type > &data, const vnl_vector< Type > ¢roid, bool norm=false)
Compute the centroid size or scale for a series of points.
double MeanSquaredErrorCollection(vtkSmartPointer< vtkPolyDataCollection > collection)
Computes the MSE of all models in collection accummulatively.
void GenerateVectorField(const double newScale=0.0, const bool useNormals=false)
Generate vector field for vectors present (as an array) in the mesh at given scaling.
void DistanceMap(vtkSmartPointer< vtkPoints > loopPoints)
Compute the distance map of the mesh points given a loop (as points) assumed to be on the mesh surfac...
void ScalarCopyCollection(vtkSmartPointer< vtkPolyDataCollection > collection)
Copies the scalars over the collection (from the first mesh) assuming the meshes have the same number...
vtkIdType GetNumberOfPoints()
Returns the total number of points of the model currently held.
void LaplacianCollection(vtkSmartPointer< vtkPolyDataCollection > collection, const size_t iterations)
Smoothes all points in all the models in the collection using the Laplacian algorithm.
void AddInput(vtkSmartPointer< vtkPolyData > model)
Assigns and coninually appends meshes provided to the class.
void GenerateNormals(const int pointNormals=0)
Generate normal vectors for each point on the mesh. If pointNormals is (0,1,2), then normals are for ...
void GeneratePointModel(const double newScale)
Generate spheres of scaling for each point of the mesh.
void Clip(const coordinateType belowValue, const coordinateType aboveValue)
Clip the mesh based on a scalar threshold of the mesh scalars.
void IterativeClosestPointsRegistration(vtkSmartPointer< vtkPolyData > fixedMesh, const bool similarity=false, const int maxPoints=1024)
Computes the ICP registration of the current mesh to the one provided.
void GenerateKMeansClustering(int numberOfClusters)
Generate k-means clustering for the point positions in the mesh.
void GenerateTubes()
Generate tubes along edges of the mesh.
void ScalarRemoveCollection(vtkSmartPointer< vtkPolyDataCollection > collection)
Removes the scalars over the collection assuming the meshes have the same number of points...
void GenerateQuantisedPoints(float quantiseFactor)
Generate points of the mesh to have integral cordinates.
void SetScalars(vtkSmartPointer< vtkDataArray > modelScalars)
Sets the scalar field of the mesh (values per vertex of the surface)
void Triangulate()
Ensures the polygons in the model are triangulated. Useful when some filters required triangulation b...
static void Scale(vtkSmartPointer< vtkPolyData > model, const coordinateType scale, const bool useCentroid=true)
Scales the coordinates of each point in the model provided by scale.
void GaussianWeightScalars(float stddev, float clampValue)
Evaluate the Gaussian function with the given standard deviation for all values of the scalars on the...
vtkSmartPointer< vtkPoints > GetPoints()
Returns the points of the model.
void ClusterDecimate()
Decimate the mesh (in terms of points) using the Quadric Clustering algorithm.
void IsoSurface(vtkSmartPointer< vtkImageData > img, double minValue)
void GenerateElevation()
Generate scalar field for the mesh proportional to the elevation in the z-direction.
void FlipCollection(vtkSmartPointer< vtkPolyDataCollection > collection, const bool xAxis, const bool yAxis, const bool zAxis)
Flips all points in all the models in the collection using the axis provided.
void MatchInformation(vtkSmartPointer< vtkPolyData > matchMesh, const bool rescale)
Matches the centroid and centroid scale of the model to the one given.
void Rotate(const bool xAxis, const bool yAxis, const bool zAxis, const float angle, const coordinate centre)
Rotate the mesh along the selected axes from the centre by angle.
vtkSmartPointer< vtkPolyData > InputModel
Holds the initial model in the pipeline.
void ClipCollection(vtkSmartPointer< vtkPolyDataCollection > collection, const coordinateType aboveVal, const coordinateType belowVal)
Computes the Clipping of models via the Threshold of scalar values in place over the collection...
void ScalarDifferenceCollection(vtkSmartPointer< vtkPolyDataCollection > collection)
Computes the difference in scalars cummulatively over the collection wrt the first mesh assuming the ...
static void BinaryThresholdScalars(vtkSmartPointer< vtkPolyData > model, const coordinateType aboveVal, const coordinateType belowVal, const coordinateType insideVal=1.0, const coordinateType outsideVal=0.0)
Thresholds scalar values of mesh in place. Scalars outside the given range is set to outsideVal and s...
vtkSmartPointer< vtkPolyDataCollection > IterativeClosestPointsAlignCollection(vtkSmartPointer< vtkPolyDataCollection > collection, bool rigid=false, vtkSmartPointer< vtkTransformCollection > tCollection=0)
Aligns the collection to the mean mesh (computed internally) of the collection without needing corres...