]> Creatis software - creaVtk.git/commitdiff
#3458 box HausdorffDistancePointSetFilter
authorEduardo DAVILA <eduardo.davila@creatis.insa-lyon.fr>
Wed, 21 Apr 2021 18:19:06 +0000 (20:19 +0200)
committerEduardo DAVILA <eduardo.davila@creatis.insa-lyon.fr>
Wed, 21 Apr 2021 18:19:06 +0000 (20:19 +0200)
bbtk_creaVtk_PKG/src/bbcreaVtkHausdorffDistancePointSetFilter.cxx [new file with mode: 0644]
bbtk_creaVtk_PKG/src/bbcreaVtkHausdorffDistancePointSetFilter.h [new file with mode: 0644]
lib/creaVtk/vtkHausdorffDistancePointSetFilter.cxx [new file with mode: 0644]
lib/creaVtk/vtkHausdorffDistancePointSetFilter.h [new file with mode: 0644]

diff --git a/bbtk_creaVtk_PKG/src/bbcreaVtkHausdorffDistancePointSetFilter.cxx b/bbtk_creaVtk_PKG/src/bbcreaVtkHausdorffDistancePointSetFilter.cxx
new file mode 100644 (file)
index 0000000..16b8bfd
--- /dev/null
@@ -0,0 +1,95 @@
+//===== 
+// Before editing this file, make sure it's a file of your own (i.e.: it wasn't generated from xml description; if so : your modifications will be lost)
+//===== 
+#include "bbcreaVtkHausdorffDistancePointSetFilter.h"
+#include "bbcreaVtkPackage.h"
+
+#include <vtkHausdorffDistancePointSetFilter.h>
+
+namespace bbcreaVtk
+{
+
+BBTK_ADD_BLACK_BOX_TO_PACKAGE(creaVtk,HausdorffDistancePointSetFilter)
+BBTK_BLACK_BOX_IMPLEMENTATION(HausdorffDistancePointSetFilter,bbtk::AtomicBlackBox);
+//===== 
+// Before editing this file, make sure it's a file of your own (i.e.: it wasn't generated from xml description; if so : your modifications will be lost)
+//===== 
+void HausdorffDistancePointSetFilter::Process()
+{
+
+// THE MAIN PROCESSING METHOD BODY
+//   Here we simply set the input 'In' value to the output 'Out'
+//   And print out the output value
+// INPUT/OUTPUT ACCESSORS ARE OF THE FORM :
+//    void bbSet{Input|Output}NAME(const TYPE&)
+//    const TYPE& bbGet{Input|Output}NAME() const 
+//    Where :
+//    * NAME is the name of the input/output
+//      (the one provided in the attribute 'name' of the tag 'input')
+//    * TYPE is the C++ type of the input/output
+//      (the one provided in the attribute 'type' of the tag 'input')
+
+//    bbSetOutputOut( bbGetInputIn() );
+//    std::cout << "Output value = " <<bbGetOutputOut() << std::endl;
+
+       if ((bbGetInputInA()!=NULL) &&  (bbGetInputInB()!=NULL)  ) 
+       {
+               vtkHausdorffDistancePointSetFilter *hausdorff = vtkHausdorffDistancePointSetFilter::New();
+               hausdorff->SetInputData(0, bbGetInputInA() );
+               hausdorff->SetInputData(1, bbGetInputInB() );           
+               
+//             hausdorff->SetTargetDistanceMethodToPointToCell();
+               hausdorff->SetTargetDistanceMethodToPointToPoint();             
+               
+               hausdorff->Update();
+               double rdAB,rdBA,hd;
+               hausdorff->GetRelativeDistance(rdAB,rdBA);              
+               hd=hausdorff->GetHausdorffDistance();
+               bbSetOutputRelativeDistanceAtoB( rdAB );
+               bbSetOutputRelativeDistanceBtoA( rdBA );
+               bbSetOutputHausdorffDistance( hd );
+               bbSetOutputOutA( (vtkPolyData*) (hausdorff->GetOutput(0)) );
+               bbSetOutputOutB( (vtkPolyData*) (hausdorff->GetOutput(1)) );
+       } // if 
+}
+//===== 
+// Before editing this file, make sure it's a file of your own (i.e.: it wasn't generated from xml description; if so : your modifications will be lost)
+//===== 
+void HausdorffDistancePointSetFilter::bbUserSetDefaultValues()
+{
+
+//  SET HERE THE DEFAULT INPUT/OUTPUT VALUES OF YOUR BOX 
+//    Here we initialize the input 'In' to 0
+   bbSetInputInA(NULL);
+   bbSetInputInB(NULL);
+  
+}
+//===== 
+// Before editing this file, make sure it's a file of your own (i.e.: it wasn't generated from xml description; if so : your modifications will be lost)
+//===== 
+void HausdorffDistancePointSetFilter::bbUserInitializeProcessing()
+{
+
+//  THE INITIALIZATION METHOD BODY :
+//    Here does nothing 
+//    but this is where you should allocate the internal/output pointers 
+//    if any 
+
+  
+}
+//===== 
+// Before editing this file, make sure it's a file of your own (i.e.: it wasn't generated from xml description; if so : your modifications will be lost)
+//===== 
+void HausdorffDistancePointSetFilter::bbUserFinalizeProcessing()
+{
+
+//  THE FINALIZATION METHOD BODY :
+//    Here does nothing 
+//    but this is where you should desallocate the internal/output pointers 
+//    if any
+  
+}
+}
+// EO namespace bbcreaVtk
+
+
diff --git a/bbtk_creaVtk_PKG/src/bbcreaVtkHausdorffDistancePointSetFilter.h b/bbtk_creaVtk_PKG/src/bbcreaVtkHausdorffDistancePointSetFilter.h
new file mode 100644 (file)
index 0000000..4828067
--- /dev/null
@@ -0,0 +1,63 @@
+//===== 
+// Before editing this file, make sure it's a file of your own (i.e.: it wasn't generated from xml description; if so : your modifications will be lost)
+//===== 
+#ifndef __bbcreaVtkHausdorffDistancePointSetFilter_h_INCLUDED__
+#define __bbcreaVtkHausdorffDistancePointSetFilter_h_INCLUDED__
+
+#include "bbcreaVtk_EXPORT.h"
+#include "bbtkAtomicBlackBox.h"
+#include "iostream"
+
+#include <vtkPolyData.h>
+
+namespace bbcreaVtk
+{
+
+class bbcreaVtk_EXPORT HausdorffDistancePointSetFilter
+ : 
+   public bbtk::AtomicBlackBox
+{
+  BBTK_BLACK_BOX_INTERFACE(HausdorffDistancePointSetFilter,bbtk::AtomicBlackBox);
+//===== 
+// Before editing this file, make sure it's a file of your own (i.e.: it wasn't generated from xml description; if so : your modifications will be lost)
+//===== 
+  BBTK_DECLARE_INPUT(InA,vtkPolyData*);
+  BBTK_DECLARE_INPUT(InB,vtkPolyData*);
+
+  BBTK_DECLARE_OUTPUT(RelativeDistanceAtoB,double);
+  BBTK_DECLARE_OUTPUT(RelativeDistanceBtoA,double);
+  BBTK_DECLARE_OUTPUT(HausdorffDistance,double);
+  BBTK_DECLARE_OUTPUT(OutA,vtkPolyData*);
+  BBTK_DECLARE_OUTPUT(OutB,vtkPolyData*);
+  
+  BBTK_PROCESS(Process);
+  void Process();
+//===== 
+// Before editing this file, make sure it's a file of your own (i.e.: it wasn't generated from xml description; if so : your modifications will be lost)
+//===== 
+};
+
+BBTK_BEGIN_DESCRIBE_BLACK_BOX(HausdorffDistancePointSetFilter,bbtk::AtomicBlackBox);
+  BBTK_NAME("HausdorffDistancePointSetFilter");
+  BBTK_AUTHOR("InfoDev");
+  BBTK_DESCRIPTION("Output Mesh with HausdorffDistance and RelativeDistance vector information ");
+  BBTK_CATEGORY("empty");
+
+  BBTK_INPUT(HausdorffDistancePointSetFilter,InA,"Mesh A",vtkPolyData*,"");
+  BBTK_INPUT(HausdorffDistancePointSetFilter,InB,"Mesh B",vtkPolyData*,"");
+
+  BBTK_OUTPUT(HausdorffDistancePointSetFilter,RelativeDistanceAtoB,"Relative distance A to B",double,"");
+  BBTK_OUTPUT(HausdorffDistancePointSetFilter,RelativeDistanceBtoA,"Relative distance B to A",double,"");
+  BBTK_OUTPUT(HausdorffDistancePointSetFilter,HausdorffDistance,"Hausdorff distance",double,"");
+  
+  BBTK_OUTPUT(HausdorffDistancePointSetFilter,OutA,"Output Mesh with 'Distance' vector information",vtkPolyData*,"");
+  BBTK_OUTPUT(HausdorffDistancePointSetFilter,OutB,"Output Mesh with 'Distance' vector information",vtkPolyData*,"");
+BBTK_END_DESCRIBE_BLACK_BOX(HausdorffDistancePointSetFilter);
+//===== 
+// Before editing this file, make sure it's a file of your own (i.e.: it wasn't generated from xml description; if so : your modifications will be lost)
+//===== 
+}
+// EO namespace bbcreaVtk
+
+#endif // __bbcreaVtkHausdorffDistancePointSetFilter_h_INCLUDED__
+
diff --git a/lib/creaVtk/vtkHausdorffDistancePointSetFilter.cxx b/lib/creaVtk/vtkHausdorffDistancePointSetFilter.cxx
new file mode 100644 (file)
index 0000000..fde86bc
--- /dev/null
@@ -0,0 +1,269 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkHausdorffDistancePointSetFilter.cxx
+
+  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+// Copyright (c) 2011 LTSI INSERM U642
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+//     * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation and/or
+// other materials provided with the distribution.
+//     * Neither name of LTSI, INSERM nor the names
+// of any contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "vtkHausdorffDistancePointSetFilter.h"
+
+#include "vtkDoubleArray.h"
+#include "vtkInformation.h"
+#include "vtkInformationVector.h"
+#include "vtkObjectFactory.h"
+#include "vtkPointData.h"
+
+#include "vtkCellLocator.h"
+#include "vtkGenericCell.h"
+#include "vtkKdTreePointLocator.h"
+#include "vtkPointSet.h"
+#include "vtkSmartPointer.h"
+
+vtkStandardNewMacro(vtkHausdorffDistancePointSetFilter);
+
+//------------------------------------------------------------------------------
+vtkHausdorffDistancePointSetFilter::vtkHausdorffDistancePointSetFilter()
+{
+  this->RelativeDistance[0] = 0.0;
+  this->RelativeDistance[1] = 0.0;
+  this->HausdorffDistance = 0.0;
+
+  this->SetNumberOfInputPorts(2);
+  this->SetNumberOfInputConnections(0, 1);
+  this->SetNumberOfInputConnections(1, 1);
+
+  this->SetNumberOfOutputPorts(2);
+
+  this->TargetDistanceMethod = POINT_TO_POINT;
+}
+
+//------------------------------------------------------------------------------
+vtkHausdorffDistancePointSetFilter::~vtkHausdorffDistancePointSetFilter() = default;
+
+//------------------------------------------------------------------------------
+int vtkHausdorffDistancePointSetFilter::RequestData(vtkInformation* vtkNotUsed(request),
+  vtkInformationVector** inputVector, vtkInformationVector* outputVector)
+{
+  // Get the info objects
+  vtkInformation* inInfoA = inputVector[0]->GetInformationObject(0);
+  vtkInformation* inInfoB = inputVector[1]->GetInformationObject(0);
+  vtkInformation* outInfoA = outputVector->GetInformationObject(0);
+  vtkInformation* outInfoB = outputVector->GetInformationObject(1);
+
+  if (inInfoA == nullptr || inInfoB == nullptr)
+  {
+    return 0;
+  }
+
+  // Get the input
+  vtkPointSet* inputA = vtkPointSet::SafeDownCast(inInfoA->Get(vtkDataObject::DATA_OBJECT()));
+  vtkPointSet* inputB = vtkPointSet::SafeDownCast(inInfoB->Get(vtkDataObject::DATA_OBJECT()));
+  vtkPointSet* outputA = vtkPointSet::SafeDownCast(outInfoA->Get(vtkDataObject::DATA_OBJECT()));
+  vtkPointSet* outputB = vtkPointSet::SafeDownCast(outInfoB->Get(vtkDataObject::DATA_OBJECT()));
+
+  if (inputA->GetNumberOfPoints() == 0 || inputB->GetNumberOfPoints() == 0)
+  {
+    return 0;
+  }
+
+  // Re-initialize the distances
+  this->RelativeDistance[0] = 0.0;
+  this->RelativeDistance[1] = 0.0;
+  this->HausdorffDistance = 0.0;
+
+  // TODO: using vtkStaticCellLocator, vtkStaticPointLocator is going to be much faster.
+  // Need to investigate and replace if appropriate.
+  vtkSmartPointer<vtkKdTreePointLocator> pointLocatorA =
+    vtkSmartPointer<vtkKdTreePointLocator>::New();
+  vtkSmartPointer<vtkKdTreePointLocator> pointLocatorB =
+    vtkSmartPointer<vtkKdTreePointLocator>::New();
+
+  vtkSmartPointer<vtkCellLocator> cellLocatorA = vtkSmartPointer<vtkCellLocator>::New();
+  vtkSmartPointer<vtkCellLocator> cellLocatorB = vtkSmartPointer<vtkCellLocator>::New();
+
+  if (this->TargetDistanceMethod == POINT_TO_POINT)
+  {
+    pointLocatorA->SetDataSet(inputA);
+    pointLocatorA->BuildLocator();
+    pointLocatorB->SetDataSet(inputB);
+    pointLocatorB->BuildLocator();
+  }
+  else
+  {
+    cellLocatorA->SetDataSet(inputA);
+    cellLocatorA->BuildLocator();
+    cellLocatorB->SetDataSet(inputB);
+    cellLocatorB->BuildLocator();
+  }
+
+  double dist;
+  double currentPoint[3];
+  double closestPoint[3];
+  vtkIdType cellId;
+  vtkSmartPointer<vtkGenericCell> cell = vtkSmartPointer<vtkGenericCell>::New();
+  int subId;
+
+  vtkSmartPointer<vtkDoubleArray> distanceAToB = vtkSmartPointer<vtkDoubleArray>::New();
+  distanceAToB->SetNumberOfComponents(1);
+  distanceAToB->SetNumberOfTuples(inputA->GetNumberOfPoints());
+  distanceAToB->SetName("Distance");
+
+  vtkSmartPointer<vtkDoubleArray> distanceBToA = vtkSmartPointer<vtkDoubleArray>::New();
+  distanceBToA->SetNumberOfComponents(1);
+  distanceBToA->SetNumberOfTuples(inputB->GetNumberOfPoints());
+  distanceBToA->SetName("Distance");
+
+  // Find the nearest neighbors to each point and add edges between them,
+  // if they do not already exist and they are not self loops
+  for (int i = 0; i < inputA->GetNumberOfPoints(); i++)
+  {
+    inputA->GetPoint(i, currentPoint);
+    if (this->TargetDistanceMethod == POINT_TO_POINT)
+    {
+      vtkIdType closestPointId = pointLocatorB->FindClosestPoint(currentPoint);
+      inputB->GetPoint(closestPointId, closestPoint);
+    }
+    else
+    {
+      cellLocatorB->FindClosestPoint(currentPoint, closestPoint, cell, cellId, subId, dist);
+    }
+
+    dist = std::sqrt(std::pow(currentPoint[0] - closestPoint[0], 2) +
+      std::pow(currentPoint[1] - closestPoint[1], 2) +
+      std::pow(currentPoint[2] - closestPoint[2], 2));
+    distanceAToB->SetValue(i, dist);
+
+    if (dist > this->RelativeDistance[0])
+    {
+      this->RelativeDistance[0] = dist;
+    }
+  }
+
+  for (int i = 0; i < inputB->GetNumberOfPoints(); i++)
+  {
+    inputB->GetPoint(i, currentPoint);
+    if (this->TargetDistanceMethod == POINT_TO_POINT)
+    {
+      vtkIdType closestPointId = pointLocatorA->FindClosestPoint(currentPoint);
+      inputA->GetPoint(closestPointId, closestPoint);
+    }
+    else
+    {
+      cellLocatorA->FindClosestPoint(currentPoint, closestPoint, cell, cellId, subId, dist);
+    }
+
+    dist = std::sqrt(std::pow(currentPoint[0] - closestPoint[0], 2) +
+      std::pow(currentPoint[1] - closestPoint[1], 2) +
+      std::pow(currentPoint[2] - closestPoint[2], 2));
+    distanceBToA->SetValue(i, dist);
+
+    if (dist > this->RelativeDistance[1])
+    {
+      this->RelativeDistance[1] = dist;
+    }
+  }
+
+  if (this->RelativeDistance[0] >= RelativeDistance[1])
+  {
+    this->HausdorffDistance = this->RelativeDistance[0];
+  }
+  else
+  {
+    this->HausdorffDistance = this->RelativeDistance[1];
+  }
+
+  vtkSmartPointer<vtkDoubleArray> relativeDistanceAtoB = vtkSmartPointer<vtkDoubleArray>::New();
+  relativeDistanceAtoB->SetNumberOfComponents(1);
+  relativeDistanceAtoB->SetName("RelativeDistanceAtoB");
+  relativeDistanceAtoB->InsertNextValue(RelativeDistance[0]);
+
+  vtkSmartPointer<vtkDoubleArray> relativeDistanceBtoA = vtkSmartPointer<vtkDoubleArray>::New();
+  relativeDistanceBtoA->SetNumberOfComponents(1);
+  relativeDistanceBtoA->SetName("RelativeDistanceBtoA");
+  relativeDistanceBtoA->InsertNextValue(RelativeDistance[1]);
+
+  vtkSmartPointer<vtkDoubleArray> hausdorffDistanceFieldDataA =
+    vtkSmartPointer<vtkDoubleArray>::New();
+  hausdorffDistanceFieldDataA->SetNumberOfComponents(1);
+  hausdorffDistanceFieldDataA->SetName("HausdorffDistance");
+  hausdorffDistanceFieldDataA->InsertNextValue(HausdorffDistance);
+
+  vtkSmartPointer<vtkDoubleArray> hausdorffDistanceFieldDataB =
+    vtkSmartPointer<vtkDoubleArray>::New();
+  hausdorffDistanceFieldDataB->SetNumberOfComponents(1);
+  hausdorffDistanceFieldDataB->SetName("HausdorffDistance");
+  hausdorffDistanceFieldDataB->InsertNextValue(HausdorffDistance);
+
+  outputA->DeepCopy(inputA);
+  outputA->GetPointData()->AddArray(distanceAToB);
+  outputA->GetFieldData()->AddArray(relativeDistanceAtoB);
+  outputA->GetFieldData()->AddArray(hausdorffDistanceFieldDataA);
+
+  outputB->DeepCopy(inputB);
+  outputB->GetPointData()->AddArray(distanceBToA);
+  outputB->GetFieldData()->AddArray(relativeDistanceBtoA);
+  outputB->GetFieldData()->AddArray(hausdorffDistanceFieldDataB);
+
+  return 1;
+}
+
+//------------------------------------------------------------------------------
+int vtkHausdorffDistancePointSetFilter::FillInputPortInformation(int port, vtkInformation* info)
+{
+  // The input should be two vtkPointsSets
+  if (port == 0)
+  {
+    info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkPointSet");
+    return 1;
+  }
+  if (port == 1)
+  {
+    info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkPointSet");
+    return 1;
+  }
+  return 0;
+}
+
+//------------------------------------------------------------------------------
+void vtkHausdorffDistancePointSetFilter::PrintSelf(ostream& os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os, indent);
+  os << indent << "HausdorffDistance: " << this->GetHausdorffDistance() << "\n";
+  os << indent << "RelativeDistance: " << this->GetRelativeDistance()[0] << ", "
+     << this->GetRelativeDistance()[1] << "\n";
+  os << indent << "TargetDistanceMethod: " << this->GetTargetDistanceMethodAsString() << "\n";
+}
+
diff --git a/lib/creaVtk/vtkHausdorffDistancePointSetFilter.h b/lib/creaVtk/vtkHausdorffDistancePointSetFilter.h
new file mode 100644 (file)
index 0000000..ddff5cf
--- /dev/null
@@ -0,0 +1,145 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkHausdorffDistancePointSetFilter.h
+
+  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+// Copyright (c) 2011 LTSI INSERM U642
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+//     * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation and/or
+// other materials provided with the distribution.
+//     * Neither name of LTSI, INSERM nor the names
+// of any contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+/** @class vtkHausdorffDistancePointSetFilter
+ *  @brief Compute Hausdorff distance between two point sets
+ *
+ * This class computes the relative and hausdorff distances from two point
+ * sets (input port 0 and input port 1). If no topology is specified (ie.
+ * vtkPointSet or vtkPolyData without vtkPolys), the distances are
+ * computed between point location. If polys exist (ie triangulation),
+ * the TargetDistanceMethod allows for an interpolation of the cells to
+ * ensure a better minimal distance exploration.
+ *
+ * The outputs (port 0 and 1) have the same geometry and topology as its
+ * respective input port. Two FieldData arrays are added : HausdorffDistance
+ * and RelativeDistance. The former is equal on both outputs whereas the
+ * latter may differ. A PointData containing the specific point minimal
+ * distance is also added to both outputs.
+ *
+ * @author Frederic Commandeur
+ * @author Jerome Velut
+ * @author LTSI
+ *
+ * @see https://www.vtkjournal.org/browse/publication/839
+ */
+
+#ifndef vtkHausdorffDistancePointSetFilter_h
+#define vtkHausdorffDistancePointSetFilter_h
+
+#include "vtkFiltersModelingModule.h" // For export macro
+#include "vtkPointSetAlgorithm.h"
+
+class VTKFILTERSMODELING_EXPORT vtkHausdorffDistancePointSetFilter : public vtkPointSetAlgorithm
+{
+public:
+  ///@{
+  /**
+   * Standard methods for construction, type and printing.
+   */
+  static vtkHausdorffDistancePointSetFilter* New();
+  vtkTypeMacro(vtkHausdorffDistancePointSetFilter, vtkPointSetAlgorithm);
+  void PrintSelf(ostream& os, vtkIndent indent) override;
+  ///@}
+
+  ///@{
+  /**
+   * Get the Relative Distance from A to B and B to A.
+   */
+  vtkGetVector2Macro(RelativeDistance, double);
+  ///@}
+
+  ///@{
+  /**
+   * Get the Hausdorff Distance.
+   */
+  vtkGetMacro(HausdorffDistance, double);
+  ///@}
+
+  enum DistanceMethod
+  {
+    POINT_TO_POINT,
+    POINT_TO_CELL
+  };
+
+  ///@{
+  /**
+   * Specify the strategy for computing the distance. If no topology is specified (ie.
+   * vtkPointSet or vtkPolyData without vtkPolys), the distances are
+   * computed between point location. If polys exist (i.e. triangulation),
+   * the TargetDistanceMethod allows for an interpolation of the cells to
+   * ensure a better minimal distance exploration.
+   *
+   */
+  vtkSetMacro(TargetDistanceMethod, int);
+  vtkGetMacro(TargetDistanceMethod, int);
+  void SetTargetDistanceMethodToPointToPoint() { this->SetTargetDistanceMethod(POINT_TO_POINT); }
+  void SetTargetDistanceMethodToPointToCell() { this->SetTargetDistanceMethod(POINT_TO_CELL); }
+  const char* GetTargetDistanceMethodAsString();
+  ///@}
+
+protected:
+  vtkHausdorffDistancePointSetFilter();
+  ~vtkHausdorffDistancePointSetFilter() override;
+
+  int RequestData(vtkInformation*, vtkInformationVector**, vtkInformationVector*) override;
+  int FillInputPortInformation(int port, vtkInformation* info) override;
+
+  int TargetDistanceMethod;   //!< point-to-point if 0, point-to-cell if 1
+  double RelativeDistance[2]; //!< relative distance between inputs
+  double HausdorffDistance;   //!< hausdorff distance (max(relative distance))
+
+private:
+  vtkHausdorffDistancePointSetFilter(const vtkHausdorffDistancePointSetFilter&) = delete;
+  void operator=(const vtkHausdorffDistancePointSetFilter&) = delete;
+};
+inline const char* vtkHausdorffDistancePointSetFilter::GetTargetDistanceMethodAsString()
+{
+  if (this->TargetDistanceMethod == POINT_TO_POINT)
+  {
+    return "PointToPoint";
+  }
+  else
+  {
+    return "PointToCell";
+  }
+}
+#endif
+