diff --git a/Filters/Points/CMakeLists.txt b/Filters/Points/CMakeLists.txt
index d7ccbb702c6d75b17827a83a11c887725abacd16..5d21c4994e0081fde81a635acb8ee8d926e995ef 100644
--- a/Filters/Points/CMakeLists.txt
+++ b/Filters/Points/CMakeLists.txt
@@ -1,25 +1,41 @@
 set(Module_SRCS
+  vtkBoundedPointSource.cxx
   vtkEllipsoidalGaussianKernel.cxx
+  vtkEuclideanClusterExtraction.cxx
+  vtkExtractHierarchicalBins.cxx
+  vtkExtractPointCloudPiece.cxx
+  vtkExtractPoints.cxx
+  vtkExtractSurface.cxx
+  vtkFitImplicitFunction.cxx
   vtkGaussianKernel.cxx
   vtkGeneralizedKernel.cxx
+  vtkHierarchicalBinningFilter.cxx
   vtkInterpolationKernel.cxx
   vtkLinearKernel.cxx
+  vtkPCACurvatureEstimation.cxx
+  vtkPCANormalEstimation.cxx
+  vtkPointCloudFilter.cxx
   vtkPointInterpolator.cxx
   vtkPointInterpolator2D.cxx
   vtkProbabilisticVoronoiKernel.cxx
+  vtkRadiusOutlierRemoval.cxx
   vtkSPHInterpolator.cxx
   vtkSPHCubicKernel.cxx
   vtkSPHKernel.cxx
   vtkSPHQuarticKernel.cxx
   vtkSPHQuinticKernel.cxx
   vtkShepardKernel.cxx
-  vtkWendlandQuinticKernel.cxx
+  vtkSignedDistance.cxx
+  vtkStatisticalOutlierRemoval.cxx
+  vtkVoxelGrid.cxx
   vtkVoronoiKernel.cxx
+  vtkWendlandQuinticKernel.cxx
   )
 
 set_source_files_properties(
   vtkGeneralizedKernel.cxx
   vtkInterpolationKernel
+  vtkPointCloudFilter
   ABSTRACT
   )
 
diff --git a/Filters/Points/Testing/Data/Baseline/TestEuclideanClusterExtraction.png.md5 b/Filters/Points/Testing/Data/Baseline/TestEuclideanClusterExtraction.png.md5
new file mode 100644
index 0000000000000000000000000000000000000000..43fc95762b5eb1868af63a42b30694d7ac56f8c5
--- /dev/null
+++ b/Filters/Points/Testing/Data/Baseline/TestEuclideanClusterExtraction.png.md5
@@ -0,0 +1 @@
+23961f1382fdf6df7918940bf0e73bbd
diff --git a/Filters/Points/Testing/Data/Baseline/TestEuclideanClusterExtraction2.png.md5 b/Filters/Points/Testing/Data/Baseline/TestEuclideanClusterExtraction2.png.md5
new file mode 100644
index 0000000000000000000000000000000000000000..59e0e86c5a800325156e61c372a086b31b752b21
--- /dev/null
+++ b/Filters/Points/Testing/Data/Baseline/TestEuclideanClusterExtraction2.png.md5
@@ -0,0 +1 @@
+3174c28fc3324676cbf5074c553b9bf6
diff --git a/Filters/Points/Testing/Data/Baseline/TestEuclideanClusterExtraction2_1.png.md5 b/Filters/Points/Testing/Data/Baseline/TestEuclideanClusterExtraction2_1.png.md5
new file mode 100644
index 0000000000000000000000000000000000000000..b3f4e4fde4e98e316177adf1cefe078946cf43cb
--- /dev/null
+++ b/Filters/Points/Testing/Data/Baseline/TestEuclideanClusterExtraction2_1.png.md5
@@ -0,0 +1 @@
+a65f2bce5e7812d47bb7f00c39538d55
diff --git a/Filters/Points/Testing/Data/Baseline/TestEuclideanClusterExtraction_1.png.md5 b/Filters/Points/Testing/Data/Baseline/TestEuclideanClusterExtraction_1.png.md5
new file mode 100644
index 0000000000000000000000000000000000000000..cad16606f05acb8deee7a7da5ce0b69422d3e729
--- /dev/null
+++ b/Filters/Points/Testing/Data/Baseline/TestEuclideanClusterExtraction_1.png.md5
@@ -0,0 +1 @@
+43ba4fd2cd361108383cc986eea311f1
diff --git a/Filters/Points/Testing/Data/Baseline/TestEuclideanClusterExtraction_2.png.md5 b/Filters/Points/Testing/Data/Baseline/TestEuclideanClusterExtraction_2.png.md5
new file mode 100644
index 0000000000000000000000000000000000000000..b292e4a1752c8395d8e985c6d86a8b2b7229b497
--- /dev/null
+++ b/Filters/Points/Testing/Data/Baseline/TestEuclideanClusterExtraction_2.png.md5
@@ -0,0 +1 @@
+3915fe2882fe6a9c68075166cd803cbd
diff --git a/Filters/Points/Testing/Data/Baseline/TestExtractPoints.png.md5 b/Filters/Points/Testing/Data/Baseline/TestExtractPoints.png.md5
new file mode 100644
index 0000000000000000000000000000000000000000..5eebc86ad4b1de21c8343440d2db37de3f7832ad
--- /dev/null
+++ b/Filters/Points/Testing/Data/Baseline/TestExtractPoints.png.md5
@@ -0,0 +1 @@
+5d1c2af24bf493178bbc00a94d3bbb4c
diff --git a/Filters/Points/Testing/Data/Baseline/TestExtractPoints_1.png.md5 b/Filters/Points/Testing/Data/Baseline/TestExtractPoints_1.png.md5
new file mode 100644
index 0000000000000000000000000000000000000000..d1b3dc60fe5a28007cdb061f7fe036a998526d60
--- /dev/null
+++ b/Filters/Points/Testing/Data/Baseline/TestExtractPoints_1.png.md5
@@ -0,0 +1 @@
+655ccab43147a28b67712a2339ae7481
diff --git a/Filters/Points/Testing/Data/Baseline/TestFitImplicitFunction.png.md5 b/Filters/Points/Testing/Data/Baseline/TestFitImplicitFunction.png.md5
new file mode 100644
index 0000000000000000000000000000000000000000..05ce6201e2211c2b078adbed7d0b4d91181f59bb
--- /dev/null
+++ b/Filters/Points/Testing/Data/Baseline/TestFitImplicitFunction.png.md5
@@ -0,0 +1 @@
+e904feb0254e876ac9e3f1a0af547e6a
diff --git a/Filters/Points/Testing/Data/Baseline/TestFitImplicitFunction_1.png.md5 b/Filters/Points/Testing/Data/Baseline/TestFitImplicitFunction_1.png.md5
new file mode 100644
index 0000000000000000000000000000000000000000..20412321453d1832a2af97edcf4a9778772bf508
--- /dev/null
+++ b/Filters/Points/Testing/Data/Baseline/TestFitImplicitFunction_1.png.md5
@@ -0,0 +1 @@
+a3f524867365311f687e8cd7550f0d08
diff --git a/Filters/Points/Testing/Data/Baseline/TestHierarchicalBinningFilter.png.md5 b/Filters/Points/Testing/Data/Baseline/TestHierarchicalBinningFilter.png.md5
new file mode 100644
index 0000000000000000000000000000000000000000..425b605747eda4c342a99fd94f2bfa0841c336c8
--- /dev/null
+++ b/Filters/Points/Testing/Data/Baseline/TestHierarchicalBinningFilter.png.md5
@@ -0,0 +1 @@
+4e97477d4d5ddc530415ee35a86c5282
diff --git a/Filters/Points/Testing/Data/Baseline/TestHierarchicalBinningFilter_1.png.md5 b/Filters/Points/Testing/Data/Baseline/TestHierarchicalBinningFilter_1.png.md5
new file mode 100644
index 0000000000000000000000000000000000000000..48427fb187a7817aa3be955d192ba9b4af4357b7
--- /dev/null
+++ b/Filters/Points/Testing/Data/Baseline/TestHierarchicalBinningFilter_1.png.md5
@@ -0,0 +1 @@
+3d653c1926584ada2454e0ef484c484d
diff --git a/Filters/Points/Testing/Data/Baseline/TestHierarchicalBinningFilter_2.png.md5 b/Filters/Points/Testing/Data/Baseline/TestHierarchicalBinningFilter_2.png.md5
new file mode 100644
index 0000000000000000000000000000000000000000..8d5f2b13d3fcaa7c8e098be47ea6421e4b58135c
--- /dev/null
+++ b/Filters/Points/Testing/Data/Baseline/TestHierarchicalBinningFilter_2.png.md5
@@ -0,0 +1 @@
+8b054573ae82aa3a993a51655f4ac797
diff --git a/Filters/Points/Testing/Data/Baseline/TestPCACurvatureEstimation.png.md5 b/Filters/Points/Testing/Data/Baseline/TestPCACurvatureEstimation.png.md5
new file mode 100644
index 0000000000000000000000000000000000000000..6af265a005e1d5353bc984b579b2391aee342a68
--- /dev/null
+++ b/Filters/Points/Testing/Data/Baseline/TestPCACurvatureEstimation.png.md5
@@ -0,0 +1 @@
+dee171c1554600081adf8528d1dcbe8a
diff --git a/Filters/Points/Testing/Data/Baseline/TestPCACurvatureEstimation2.png.md5 b/Filters/Points/Testing/Data/Baseline/TestPCACurvatureEstimation2.png.md5
new file mode 100644
index 0000000000000000000000000000000000000000..a06cfe737132dde9ecbeabb039bbf4d0417a846f
--- /dev/null
+++ b/Filters/Points/Testing/Data/Baseline/TestPCACurvatureEstimation2.png.md5
@@ -0,0 +1 @@
+df39e44bedd134a825b69b8ae0942d03
diff --git a/Filters/Points/Testing/Data/Baseline/TestPCACurvatureEstimation_1.png.md5 b/Filters/Points/Testing/Data/Baseline/TestPCACurvatureEstimation_1.png.md5
new file mode 100644
index 0000000000000000000000000000000000000000..740be5646d5dd52b04204c329b6766e3c819274a
--- /dev/null
+++ b/Filters/Points/Testing/Data/Baseline/TestPCACurvatureEstimation_1.png.md5
@@ -0,0 +1 @@
+29e74ccf4fd4240c2d79fd26371db896
diff --git a/Filters/Points/Testing/Data/Baseline/TestPCANormalEstimation.png.md5 b/Filters/Points/Testing/Data/Baseline/TestPCANormalEstimation.png.md5
new file mode 100644
index 0000000000000000000000000000000000000000..366c2d7733c5b62830972df806f769bbc312b2e5
--- /dev/null
+++ b/Filters/Points/Testing/Data/Baseline/TestPCANormalEstimation.png.md5
@@ -0,0 +1 @@
+0207fa43dbcc7f5587ae15d1f21ec11e
diff --git a/Filters/Points/Testing/Data/Baseline/TestPCANormalEstimation2.png.md5 b/Filters/Points/Testing/Data/Baseline/TestPCANormalEstimation2.png.md5
new file mode 100644
index 0000000000000000000000000000000000000000..062fa71c466cfe43873e668a8c1b4eb8112c8c65
--- /dev/null
+++ b/Filters/Points/Testing/Data/Baseline/TestPCANormalEstimation2.png.md5
@@ -0,0 +1 @@
+1559fe90bfc8772c10e335f83e3e0467
diff --git a/Filters/Points/Testing/Data/Baseline/TestPCANormalEstimation2_1.png.md5 b/Filters/Points/Testing/Data/Baseline/TestPCANormalEstimation2_1.png.md5
new file mode 100644
index 0000000000000000000000000000000000000000..54f3ca9ebf91250338a2fdcc60527f020c10b36d
--- /dev/null
+++ b/Filters/Points/Testing/Data/Baseline/TestPCANormalEstimation2_1.png.md5
@@ -0,0 +1 @@
+7fb2cab5ee8453c0b0315aeb36edb76b
diff --git a/Filters/Points/Testing/Data/Baseline/TestPCANormalEstimation2_2.png.md5 b/Filters/Points/Testing/Data/Baseline/TestPCANormalEstimation2_2.png.md5
new file mode 100644
index 0000000000000000000000000000000000000000..ab8d02ae1f26be8bdb3b61b2146852dd5c1977cb
--- /dev/null
+++ b/Filters/Points/Testing/Data/Baseline/TestPCANormalEstimation2_2.png.md5
@@ -0,0 +1 @@
+9185bf2ccbe279bf4a3cdc989254a019
diff --git a/Filters/Points/Testing/Data/Baseline/TestPCANormalEstimation_1.png.md5 b/Filters/Points/Testing/Data/Baseline/TestPCANormalEstimation_1.png.md5
new file mode 100644
index 0000000000000000000000000000000000000000..1199c5deefbe6724c184584a10d9f32d852641b5
--- /dev/null
+++ b/Filters/Points/Testing/Data/Baseline/TestPCANormalEstimation_1.png.md5
@@ -0,0 +1 @@
+cedad82c1dad87a0de0949d55bbeb1e5
diff --git a/Filters/Points/Testing/Data/Baseline/TestPCANormalEstimation_2.png.md5 b/Filters/Points/Testing/Data/Baseline/TestPCANormalEstimation_2.png.md5
new file mode 100644
index 0000000000000000000000000000000000000000..2d1236417db09e6d34df765b63530de29bfe4b83
--- /dev/null
+++ b/Filters/Points/Testing/Data/Baseline/TestPCANormalEstimation_2.png.md5
@@ -0,0 +1 @@
+152a15045f918455f93af5f00c2be206
diff --git a/Filters/Points/Testing/Data/Baseline/TestRadiusOutlierRemoval.png.md5 b/Filters/Points/Testing/Data/Baseline/TestRadiusOutlierRemoval.png.md5
new file mode 100644
index 0000000000000000000000000000000000000000..7796bab910e14b90f8e667df26901decbd9ba6bb
--- /dev/null
+++ b/Filters/Points/Testing/Data/Baseline/TestRadiusOutlierRemoval.png.md5
@@ -0,0 +1 @@
+a72aa4ac4b715301840928e0d27fec67
diff --git a/Filters/Points/Testing/Data/Baseline/TestRadiusOutlierRemoval_1.png.md5 b/Filters/Points/Testing/Data/Baseline/TestRadiusOutlierRemoval_1.png.md5
new file mode 100644
index 0000000000000000000000000000000000000000..394e43c8568a5c60a8263a422926695431fcc16c
--- /dev/null
+++ b/Filters/Points/Testing/Data/Baseline/TestRadiusOutlierRemoval_1.png.md5
@@ -0,0 +1 @@
+7e186d4187dae54b80ee4d14257bc1aa
diff --git a/Filters/Points/Testing/Data/Baseline/TestRadiusOutlierRemoval_2.png.md5 b/Filters/Points/Testing/Data/Baseline/TestRadiusOutlierRemoval_2.png.md5
new file mode 100644
index 0000000000000000000000000000000000000000..0653e87f9a1ce4364d6b4e03558669b2a4895b63
--- /dev/null
+++ b/Filters/Points/Testing/Data/Baseline/TestRadiusOutlierRemoval_2.png.md5
@@ -0,0 +1 @@
+307f4526d74f10adb8767248ea9dadd6
diff --git a/Filters/Points/Testing/Data/Baseline/TestSignedDistanceFilter.png.md5 b/Filters/Points/Testing/Data/Baseline/TestSignedDistanceFilter.png.md5
new file mode 100644
index 0000000000000000000000000000000000000000..29e8545cddd2e948f600474cdc2d09d12d95b3de
--- /dev/null
+++ b/Filters/Points/Testing/Data/Baseline/TestSignedDistanceFilter.png.md5
@@ -0,0 +1 @@
+565e56447abef5fda7b2da5f00c8fc85
diff --git a/Filters/Points/Testing/Data/Baseline/TestSignedDistanceFilter_1.png.md5 b/Filters/Points/Testing/Data/Baseline/TestSignedDistanceFilter_1.png.md5
new file mode 100644
index 0000000000000000000000000000000000000000..28f009349088db1bd8f014fc5322e38b3eee5074
--- /dev/null
+++ b/Filters/Points/Testing/Data/Baseline/TestSignedDistanceFilter_1.png.md5
@@ -0,0 +1 @@
+2feecf944487096b67f6b4160e907bdd
diff --git a/Filters/Points/Testing/Data/Baseline/TestStatisticalOutlierRemoval.png.md5 b/Filters/Points/Testing/Data/Baseline/TestStatisticalOutlierRemoval.png.md5
new file mode 100644
index 0000000000000000000000000000000000000000..710b6bb0892f2829e9eefa9c60fe2eebcacc5ba3
--- /dev/null
+++ b/Filters/Points/Testing/Data/Baseline/TestStatisticalOutlierRemoval.png.md5
@@ -0,0 +1 @@
+29f9aac6f51eb73f765e51bc9dd94a18
diff --git a/Filters/Points/Testing/Data/Baseline/TestStatisticalOutlierRemoval_1.png.md5 b/Filters/Points/Testing/Data/Baseline/TestStatisticalOutlierRemoval_1.png.md5
new file mode 100644
index 0000000000000000000000000000000000000000..c5c01f1ae09e7b61a88839cac192c26a471c9bc2
--- /dev/null
+++ b/Filters/Points/Testing/Data/Baseline/TestStatisticalOutlierRemoval_1.png.md5
@@ -0,0 +1 @@
+a0d2231d5a6d5fab718a1b26975d86dd
diff --git a/Filters/Points/Testing/Data/Baseline/TestStatisticalOutlierRemoval_2.png.md5 b/Filters/Points/Testing/Data/Baseline/TestStatisticalOutlierRemoval_2.png.md5
new file mode 100644
index 0000000000000000000000000000000000000000..84aa2f926122899fe0095c884d819cb535083dd3
--- /dev/null
+++ b/Filters/Points/Testing/Data/Baseline/TestStatisticalOutlierRemoval_2.png.md5
@@ -0,0 +1 @@
+cb108893ba2e357f1c57a95063e92b0b
diff --git a/Filters/Points/Testing/Data/Baseline/TestVoxelGridFilter.png.md5 b/Filters/Points/Testing/Data/Baseline/TestVoxelGridFilter.png.md5
new file mode 100644
index 0000000000000000000000000000000000000000..166d7bb23cadd03502a2561c028e2aedbdb956dd
--- /dev/null
+++ b/Filters/Points/Testing/Data/Baseline/TestVoxelGridFilter.png.md5
@@ -0,0 +1 @@
+47ed65bd9ec8a38c041a68f4c67b5818
diff --git a/Filters/Points/Testing/Data/Baseline/TestVoxelGridFilter_1.png.md5 b/Filters/Points/Testing/Data/Baseline/TestVoxelGridFilter_1.png.md5
new file mode 100644
index 0000000000000000000000000000000000000000..65fe799fdc06e6bf9904cfe74b1b8a85229c137f
--- /dev/null
+++ b/Filters/Points/Testing/Data/Baseline/TestVoxelGridFilter_1.png.md5
@@ -0,0 +1 @@
+81c47e145a517a14caa1feb75d1137d5
diff --git a/Filters/Points/Testing/Data/Baseline/TestVoxelGridFilter_2.png.md5 b/Filters/Points/Testing/Data/Baseline/TestVoxelGridFilter_2.png.md5
new file mode 100644
index 0000000000000000000000000000000000000000..c5fb98a2d4952abd526ee734a8080788b7ae4a4d
--- /dev/null
+++ b/Filters/Points/Testing/Data/Baseline/TestVoxelGridFilter_2.png.md5
@@ -0,0 +1 @@
+9ed77dab18ab940a57be718f3f8dae66
diff --git a/Filters/Points/Testing/Data/Baseline/TestVoxelGridFilter_3.png.md5 b/Filters/Points/Testing/Data/Baseline/TestVoxelGridFilter_3.png.md5
new file mode 100644
index 0000000000000000000000000000000000000000..31912b02fd4f6a7eafaccb89724bf6aaf9b8abbd
--- /dev/null
+++ b/Filters/Points/Testing/Data/Baseline/TestVoxelGridFilter_3.png.md5
@@ -0,0 +1 @@
+fc1399b4e6d61569132d877655c4c1dc
diff --git a/Filters/Points/Testing/Python/CMakeLists.txt b/Filters/Points/Testing/Python/CMakeLists.txt
index afaa380cdb04d70ee7b54c1d9dc78f439d6927a1..72e64ffb450d51fd080ee6ad7cee2df266a5f9db 100644
--- a/Filters/Points/Testing/Python/CMakeLists.txt
+++ b/Filters/Points/Testing/Python/CMakeLists.txt
@@ -7,3 +7,21 @@ vtk_add_test_python(
   TestSPHInterpolator.py
   TestSPHInterpolator2D.py
   )
+
+if ("${VTK_RENDERING_BACKEND}" STREQUAL "OpenGL2")
+  vtk_add_test_python(
+    TestEuclideanClusterExtraction.py
+    TestEuclideanClusterExtraction2.py
+    TestExtractPoints.py
+    TestFitImplicitFunction.py
+    TestHierarchicalBinningFilter.py
+    TestPCACurvatureEstimation.py
+    TestPCACurvatureEstimation2.py
+    TestPCANormalEstimation.py
+    TestPCANormalEstimation2.py
+    TestRadiusOutlierRemoval.py
+    TestSignedDistanceFilter.py
+    TestStatisticalOutlierRemoval.py
+    TestVoxelGridFilter.py
+    )
+endif ()
diff --git a/Filters/Points/Testing/Python/TestEuclideanClusterExtraction.py b/Filters/Points/Testing/Python/TestEuclideanClusterExtraction.py
new file mode 100755
index 0000000000000000000000000000000000000000..5a11baeb3aaf1e78481fad4c5e508b9d60eb5e77
--- /dev/null
+++ b/Filters/Points/Testing/Python/TestEuclideanClusterExtraction.py
@@ -0,0 +1,96 @@
+#!/usr/bin/env python
+import vtk
+from vtk.test import Testing
+from vtk.util.misc import vtkGetDataRoot
+VTK_DATA_ROOT = vtkGetDataRoot()
+
+# create pipeline
+#
+
+# Create a cylinder
+cyl = vtk.vtkCylinderSource()
+cyl.SetCenter(-2,0,0)
+cyl.SetRadius(0.02)
+cyl.SetHeight(1.8)
+cyl.SetResolution(24)
+
+# Create a (thin) box implicit function
+plane = vtk.vtkPlaneSource()
+plane.SetOrigin(-1, -0.5, 0)
+plane.SetPoint1(0.5, -0.5, 0)
+plane.SetPoint2(-1, 0.5, 0)
+
+# Create a sphere implicit function
+sphere = vtk.vtkSphereSource()
+sphere.SetCenter(2,0,0)
+sphere.SetRadius(0.8)
+sphere.SetThetaResolution(96)
+sphere.SetPhiResolution(48)
+
+# Boolean (union) these together
+append = vtk.vtkAppendPolyData()
+append.AddInputConnection(cyl.GetOutputPort())
+append.AddInputConnection(plane.GetOutputPort())
+append.AddInputConnection(sphere.GetOutputPort())
+
+# Extract points along sphere surface
+pts = vtk.vtkPolyDataPointSampler()
+pts.SetInputConnection(append.GetOutputPort())
+pts.SetDistance(0.025)
+pts.Update()
+
+# Now see if we can extract the three objects as separate clusters.
+extr = vtk.vtkEuclideanClusterExtraction()
+extr.SetInputConnection(pts.GetOutputPort())
+extr.SetRadius(0.1)
+extr.ColorClustersOn()
+extr.SetExtractionModeToAllClusters()
+
+# Time execution
+timer = vtk.vtkTimerLog()
+timer.StartTimer()
+extr.Update()
+timer.StopTimer()
+time = timer.GetElapsedTime()
+print("Points processed: {0}".format(pts.GetOutput().GetNumberOfPoints()))
+print("   Time to segment objects: {0}".format(time))
+print("   Number of clusters: {0}".format(extr.GetNumberOfExtractedClusters()))
+
+# Three different outputs for different curvatures
+subMapper = vtk.vtkPointGaussianMapper()
+subMapper.SetInputConnection(extr.GetOutputPort(0))
+subMapper.EmissiveOff()
+subMapper.SetScaleFactor(0.0)
+subMapper.SetScalarRange(0,2)
+
+subActor = vtk.vtkActor()
+subActor.SetMapper(subMapper)
+subActor.AddPosition(0,2.25,0)
+
+# Create the RenderWindow, Renderer and both Actors
+#
+ren0 = vtk.vtkRenderer()
+renWin = vtk.vtkRenderWindow()
+renWin.AddRenderer(ren0)
+iren = vtk.vtkRenderWindowInteractor()
+iren.SetRenderWindow(renWin)
+
+# Add the actors to the renderer, set the background and size
+#
+ren0.AddActor(subActor)
+ren0.SetBackground(0.1, 0.2, 0.4)
+
+renWin.SetSize(250,250)
+
+cam = ren0.GetActiveCamera()
+cam.SetFocalPoint(0,0,-1)
+cam.SetPosition(0,0,0)
+ren0.ResetCamera()
+
+iren.Initialize()
+
+# render the image
+#
+renWin.Render()
+
+#iren.Start()
diff --git a/Filters/Points/Testing/Python/TestEuclideanClusterExtraction2.py b/Filters/Points/Testing/Python/TestEuclideanClusterExtraction2.py
new file mode 100755
index 0000000000000000000000000000000000000000..3a8e64735acd7f8bf944f14c98fb4235c1a60576
--- /dev/null
+++ b/Filters/Points/Testing/Python/TestEuclideanClusterExtraction2.py
@@ -0,0 +1,117 @@
+#!/usr/bin/env python
+import vtk
+from vtk.test import Testing
+from vtk.util.misc import vtkGetDataRoot
+VTK_DATA_ROOT = vtkGetDataRoot()
+
+# Parameters for debugging
+NPts = 100000
+math = vtk.vtkMath()
+math.RandomSeed(31415)
+
+# create pipeline
+#
+points = vtk.vtkBoundedPointSource()
+points.SetNumberOfPoints(NPts)
+points.SetBounds(-3,3, -1,1, -1,1)
+points.ProduceRandomScalarsOff()
+points.ProduceCellOutputOff()
+
+# create some scalars based on implicit function
+# Create a cylinder
+cyl = vtk.vtkCylinder()
+cyl.SetCenter(-2,0,0)
+cyl.SetRadius(0.02)
+
+# Create a (thin) box implicit function
+box = vtk.vtkBox()
+box.SetBounds(-1,0.5, -0.5,0.5, -0.0005, 0.0005)
+
+# Create a sphere implicit function
+sphere = vtk.vtkSphere()
+sphere.SetCenter(2,0,0)
+sphere.SetRadius(0.8)
+
+# Boolean (union) these together
+imp = vtk.vtkImplicitBoolean()
+imp.SetOperationTypeToUnion()
+imp.AddFunction(cyl)
+imp.AddFunction(box)
+imp.AddFunction(sphere)
+
+# Generate scalars and vector
+sample = vtk.vtkSampleImplicitFunctionFilter()
+sample.SetInputConnection(points.GetOutputPort())
+sample.SetImplicitFunction(imp)
+sample.Update()
+print(sample.GetOutput().GetScalarRange())
+
+# Now see if we can extract the three objects as separate clusters.
+extr = vtk.vtkEuclideanClusterExtraction()
+extr.SetInputConnection(sample.GetOutputPort())
+extr.SetRadius(0.15)
+#extr.ColorClustersOn()
+#extr.SetExtractionModeToAllClusters()
+extr.SetExtractionModeToLargestCluster()
+extr.ScalarConnectivityOn()
+extr.SetScalarRange(-0.64,-.3)
+
+# Time execution
+timer = vtk.vtkTimerLog()
+timer.StartTimer()
+extr.Update()
+timer.StopTimer()
+time = timer.GetElapsedTime()
+print("Points processed: {0}".format(points.GetOutput().GetNumberOfPoints()))
+print("   Time to segment objects: {0}".format(time))
+print("   Number of clusters: {0}".format(extr.GetNumberOfExtractedClusters()))
+
+# Draw the points
+subMapper = vtk.vtkPointGaussianMapper()
+subMapper.SetInputConnection(extr.GetOutputPort(0))
+#subMapper.SetInputConnection(sample.GetOutputPort(0))
+subMapper.EmissiveOff()
+subMapper.SetScaleFactor(0.0)
+subMapper.SetScalarRange(-0.64,2.25)
+
+subActor = vtk.vtkActor()
+subActor.SetMapper(subMapper)
+
+# Create an outline
+outline = vtk.vtkOutlineFilter()
+outline.SetInputConnection(sample.GetOutputPort())
+
+outlineMapper = vtk.vtkPolyDataMapper()
+outlineMapper.SetInputConnection(outline.GetOutputPort())
+
+outlineActor = vtk.vtkActor()
+outlineActor.SetMapper(outlineMapper)
+
+# Create the RenderWindow, Renderer and both Actors
+#
+ren0 = vtk.vtkRenderer()
+renWin = vtk.vtkRenderWindow()
+renWin.AddRenderer(ren0)
+iren = vtk.vtkRenderWindowInteractor()
+iren.SetRenderWindow(renWin)
+
+# Add the actors to the renderer, set the background and size
+#
+ren0.AddActor(subActor)
+ren0.AddActor(outlineActor)
+ren0.SetBackground(0.1, 0.2, 0.4)
+
+renWin.SetSize(250,250)
+
+cam = ren0.GetActiveCamera()
+cam.SetFocalPoint(0,0,-1)
+cam.SetPosition(0,0,0)
+ren0.ResetCamera()
+
+iren.Initialize()
+
+# render the image
+#
+renWin.Render()
+
+#iren.Start()
diff --git a/Filters/Points/Testing/Python/TestExtractPoints.py b/Filters/Points/Testing/Python/TestExtractPoints.py
new file mode 100755
index 0000000000000000000000000000000000000000..37e8ebf153b742425b0d57b37dbb2e61f7086106
--- /dev/null
+++ b/Filters/Points/Testing/Python/TestExtractPoints.py
@@ -0,0 +1,91 @@
+#!/usr/bin/env python
+import vtk
+from vtk.test import Testing
+from vtk.util.misc import vtkGetDataRoot
+VTK_DATA_ROOT = vtkGetDataRoot()
+
+# Interpolate onto a volume
+
+# Parameters for debugging
+NPts = 1000000
+math = vtk.vtkMath()
+math.RandomSeed(31415)
+
+# create pipeline
+#
+points = vtk.vtkBoundedPointSource()
+points.SetNumberOfPoints(NPts)
+points.ProduceRandomScalarsOn()
+points.ProduceCellOutputOff()
+points.Update()
+
+# Create a sphere implicit function
+sphere = vtk.vtkSphere()
+sphere.SetCenter(0.9,0.1,0.1)
+sphere.SetRadius(0.33)
+
+# Extract points within sphere
+extract = vtk.vtkExtractPoints()
+extract.SetInputConnection(points.GetOutputPort())
+extract.SetImplicitFunction(sphere)
+
+# Time execution
+timer = vtk.vtkTimerLog()
+timer.StartTimer()
+extract.Update()
+timer.StopTimer()
+time = timer.GetElapsedTime()
+print("Time to remove points: {0}".format(time))
+print("   Number removed: {0}".format(extract.GetNumberOfPointsRemoved()),
+      " (out of: {}".format(NPts))
+
+# First output are the non-outliers
+extMapper = vtk.vtkPointGaussianMapper()
+extMapper.SetInputConnection(extract.GetOutputPort())
+extMapper.EmissiveOff()
+extMapper.SetScaleFactor(0.0)
+
+extActor = vtk.vtkActor()
+extActor.SetMapper(extMapper)
+
+# Create an outline
+outline = vtk.vtkOutlineFilter()
+outline.SetInputConnection(points.GetOutputPort())
+
+outlineMapper = vtk.vtkPolyDataMapper()
+outlineMapper.SetInputConnection(outline.GetOutputPort())
+
+outlineActor = vtk.vtkActor()
+outlineActor.SetMapper(outlineMapper)
+
+# Create the RenderWindow, Renderer and both Actors
+#
+ren0 = vtk.vtkRenderer()
+ren1 = vtk.vtkRenderer()
+renWin = vtk.vtkRenderWindow()
+renWin.AddRenderer(ren0)
+iren = vtk.vtkRenderWindowInteractor()
+iren.SetRenderWindow(renWin)
+
+# Add the actors to the renderer, set the background and size
+#
+ren0.AddActor(extActor)
+ren0.AddActor(outlineActor)
+ren0.SetBackground(0.1, 0.2, 0.4)
+
+renWin.SetSize(250,250)
+
+cam = ren0.GetActiveCamera()
+cam.SetFocalPoint(1,1,1)
+cam.SetPosition(0,0,0)
+ren0.ResetCamera()
+
+ren1.SetActiveCamera(cam)
+
+iren.Initialize()
+
+# render the image
+#
+renWin.Render()
+
+#iren.Start()
diff --git a/Filters/Points/Testing/Python/TestFitImplicitFunction.py b/Filters/Points/Testing/Python/TestFitImplicitFunction.py
new file mode 100755
index 0000000000000000000000000000000000000000..06cd9d7d96475147da067b68d73c2934a646ef7b
--- /dev/null
+++ b/Filters/Points/Testing/Python/TestFitImplicitFunction.py
@@ -0,0 +1,92 @@
+#!/usr/bin/env python
+import vtk
+from vtk.test import Testing
+from vtk.util.misc import vtkGetDataRoot
+VTK_DATA_ROOT = vtkGetDataRoot()
+
+# Interpolate onto a volume
+
+# Parameters for debugging
+NPts = 1000000
+math = vtk.vtkMath()
+math.RandomSeed(31415)
+
+# create pipeline
+#
+points = vtk.vtkBoundedPointSource()
+points.SetNumberOfPoints(NPts)
+points.ProduceRandomScalarsOn()
+points.ProduceCellOutputOff()
+points.Update()
+
+# Create a sphere implicit function
+sphere = vtk.vtkSphere()
+sphere.SetCenter(0.9,0.1,0.1)
+sphere.SetRadius(0.33)
+
+# Extract points within sphere
+extract = vtk.vtkFitImplicitFunction()
+extract.SetInputConnection(points.GetOutputPort())
+extract.SetImplicitFunction(sphere)
+extract.SetThreshold(0.005)
+
+# Time execution
+timer = vtk.vtkTimerLog()
+timer.StartTimer()
+extract.Update()
+timer.StopTimer()
+time = timer.GetElapsedTime()
+print("Time to extract points: {0}".format(time))
+print("   Number removed: {0}".format(extract.GetNumberOfPointsRemoved()),
+      " (out of: {}".format(NPts))
+
+# First output are the non-outliers
+extMapper = vtk.vtkPointGaussianMapper()
+extMapper.SetInputConnection(extract.GetOutputPort())
+extMapper.EmissiveOff()
+extMapper.SetScaleFactor(0.0)
+
+extActor = vtk.vtkActor()
+extActor.SetMapper(extMapper)
+
+# Create an outline
+outline = vtk.vtkOutlineFilter()
+outline.SetInputConnection(points.GetOutputPort())
+
+outlineMapper = vtk.vtkPolyDataMapper()
+outlineMapper.SetInputConnection(outline.GetOutputPort())
+
+outlineActor = vtk.vtkActor()
+outlineActor.SetMapper(outlineMapper)
+
+# Create the RenderWindow, Renderer and both Actors
+#
+ren0 = vtk.vtkRenderer()
+ren1 = vtk.vtkRenderer()
+renWin = vtk.vtkRenderWindow()
+renWin.AddRenderer(ren0)
+iren = vtk.vtkRenderWindowInteractor()
+iren.SetRenderWindow(renWin)
+
+# Add the actors to the renderer, set the background and size
+#
+ren0.AddActor(extActor)
+ren0.AddActor(outlineActor)
+ren0.SetBackground(0.1, 0.2, 0.4)
+
+renWin.SetSize(250,250)
+
+cam = ren0.GetActiveCamera()
+cam.SetFocalPoint(1,1,1)
+cam.SetPosition(0,0,0)
+ren0.ResetCamera()
+
+ren1.SetActiveCamera(cam)
+
+iren.Initialize()
+
+# render the image
+#
+renWin.Render()
+
+#iren.Start()
diff --git a/Filters/Points/Testing/Python/TestHierarchicalBinningFilter.py b/Filters/Points/Testing/Python/TestHierarchicalBinningFilter.py
new file mode 100755
index 0000000000000000000000000000000000000000..11cf26c5869196e7a2141d12f9cfb368f97831f6
--- /dev/null
+++ b/Filters/Points/Testing/Python/TestHierarchicalBinningFilter.py
@@ -0,0 +1,115 @@
+#!/usr/bin/env python
+import vtk
+from vtk.test import Testing
+from vtk.util.misc import vtkGetDataRoot
+VTK_DATA_ROOT = vtkGetDataRoot()
+
+# Interpolate onto a volume
+
+# Parameters for debugging
+NPts = 1000000
+binNum = 16
+math = vtk.vtkMath()
+math.RandomSeed(31415)
+
+# create pipeline
+#
+points = vtk.vtkBoundedPointSource()
+points.SetNumberOfPoints(NPts)
+points.ProduceRandomScalarsOn()
+points.ProduceCellOutputOff()
+points.Update()
+
+# Bin the points
+hBin = vtk.vtkHierarchicalBinningFilter()
+hBin.SetInputConnection(points.GetOutputPort())
+#hBin.AutomaticOn()
+hBin.AutomaticOff()
+hBin.SetDivisions(2,2,2)
+hBin.SetBounds(points.GetOutput().GetBounds())
+
+# Time execution
+timer = vtk.vtkTimerLog()
+timer.StartTimer()
+hBin.Update()
+timer.StopTimer()
+time = timer.GetElapsedTime()
+print("Points processed: {0}".format(NPts))
+print("   Time to bin: {0}".format(time))
+#print(hBin)
+#print(hBin.GetOutput())
+
+# write stuff out
+w = vtk.vtkXMLPolyDataWriter()
+w.SetFileName("binPoints.vtp")
+w.SetInputConnection(hBin.GetOutputPort())
+#w.SetDataModeToAscii()
+#w.Write()
+
+# Output a selected bin of points
+extBin = vtk.vtkExtractHierarchicalBins()
+extBin.SetInputConnection(hBin.GetOutputPort())
+extBin.SetBinningFilter(hBin)
+#extBin.SetLevel(0)
+extBin.SetLevel(-1)
+extBin.SetBin(binNum)
+
+subMapper = vtk.vtkPointGaussianMapper()
+subMapper.SetInputConnection(extBin.GetOutputPort())
+subMapper.EmissiveOff()
+subMapper.SetScaleFactor(0.0)
+
+subActor = vtk.vtkActor()
+subActor.SetMapper(subMapper)
+
+# Create an outline
+outline = vtk.vtkOutlineFilter()
+outline.SetInputConnection(points.GetOutputPort())
+
+outlineMapper = vtk.vtkPolyDataMapper()
+outlineMapper.SetInputConnection(outline.GetOutputPort())
+
+outlineActor = vtk.vtkActor()
+outlineActor.SetMapper(outlineMapper)
+
+# Create another outline
+bds = [0,0,0,0,0,0]
+hBin.GetBinBounds(binNum,bds)
+binOutline = vtk.vtkOutlineSource()
+binOutline.SetBounds(bds)
+
+binOutlineMapper = vtk.vtkPolyDataMapper()
+binOutlineMapper.SetInputConnection(binOutline.GetOutputPort())
+
+binOutlineActor = vtk.vtkActor()
+binOutlineActor.SetMapper(binOutlineMapper)
+
+# Create the RenderWindow, Renderer and both Actors
+#
+ren0 = vtk.vtkRenderer()
+renWin = vtk.vtkRenderWindow()
+renWin.AddRenderer(ren0)
+iren = vtk.vtkRenderWindowInteractor()
+iren.SetRenderWindow(renWin)
+
+# Add the actors to the renderer, set the background and size
+#
+ren0.AddActor(subActor)
+ren0.AddActor(outlineActor)
+ren0.AddActor(binOutlineActor)
+ren0.SetBackground(0.1, 0.2, 0.4)
+
+renWin.SetSize(250,250)
+
+cam = ren0.GetActiveCamera()
+cam.SetFocalPoint(1,1,1)
+cam.SetPosition(0,0,0)
+ren0.ResetCamera()
+
+iren.Initialize()
+
+# render the image
+#
+renWin.Render()
+
+#iren.Start()
diff --git a/Filters/Points/Testing/Python/TestPCACurvatureEstimation.py b/Filters/Points/Testing/Python/TestPCACurvatureEstimation.py
new file mode 100755
index 0000000000000000000000000000000000000000..ebf73b03d3cf717f4d2a67709fabdd44a815dc55
--- /dev/null
+++ b/Filters/Points/Testing/Python/TestPCACurvatureEstimation.py
@@ -0,0 +1,123 @@
+#!/usr/bin/env python
+import vtk
+from vtk.test import Testing
+from vtk.util.misc import vtkGetDataRoot
+VTK_DATA_ROOT = vtkGetDataRoot()
+
+# create pipeline
+#
+
+# Create a cylinder
+cyl = vtk.vtkCylinderSource()
+cyl.SetCenter(-2,0,0)
+cyl.SetRadius(0.02)
+cyl.SetHeight(1.8)
+cyl.SetResolution(24)
+
+# Create a (thin) box implicit function
+plane = vtk.vtkPlaneSource()
+plane.SetOrigin(-1, -0.5, 0)
+plane.SetPoint1(0.5, -0.5, 0)
+plane.SetPoint2(-1, 0.5, 0)
+
+# Create a sphere implicit function
+sphere = vtk.vtkSphereSource()
+sphere.SetCenter(2,0,0)
+sphere.SetRadius(0.8)
+sphere.SetThetaResolution(96)
+sphere.SetPhiResolution(48)
+
+# Boolean (union) these together
+append = vtk.vtkAppendPolyData()
+append.AddInputConnection(cyl.GetOutputPort())
+append.AddInputConnection(plane.GetOutputPort())
+append.AddInputConnection(sphere.GetOutputPort())
+
+# Extract points along sphere surface
+pts = vtk.vtkPolyDataPointSampler()
+pts.SetInputConnection(append.GetOutputPort())
+pts.SetDistance(0.01)
+pts.Update()
+
+# Now generate normals from resulting points
+curv = vtk.vtkPCACurvatureEstimation()
+curv.SetInputConnection(pts.GetOutputPort())
+curv.SetSampleSize(20)
+
+# Time execution
+timer = vtk.vtkTimerLog()
+timer.StartTimer()
+curv.Update()
+timer.StopTimer()
+time = timer.GetElapsedTime()
+print("Points processed: {0}".format(pts.GetOutput().GetNumberOfPoints()))
+print("   Time to generate curvature: {0}".format(time))
+
+# Break out the curvature into three separate arrays
+assign = vtk.vtkAssignAttribute()
+assign.SetInputConnection(curv.GetOutputPort())
+assign.Assign("PCACurvature", "VECTORS", "POINT_DATA")
+
+extract = vtk.vtkExtractVectorComponents()
+extract.SetInputConnection(assign.GetOutputPort())
+extract.Update()
+print(extract.GetOutput(0).GetScalarRange())
+print(extract.GetOutput(1).GetScalarRange())
+print(extract.GetOutput(2).GetScalarRange())
+
+# Three different outputs for different curvatures
+subMapper = vtk.vtkPointGaussianMapper()
+subMapper.SetInputConnection(extract.GetOutputPort(0))
+subMapper.EmissiveOff()
+subMapper.SetScaleFactor(0.0)
+
+subActor = vtk.vtkActor()
+subActor.SetMapper(subMapper)
+subActor.AddPosition(0,2.25,0)
+
+sub1Mapper = vtk.vtkPointGaussianMapper()
+sub1Mapper.SetInputConnection(extract.GetOutputPort(1))
+sub1Mapper.EmissiveOff()
+sub1Mapper.SetScaleFactor(0.0)
+
+sub1Actor = vtk.vtkActor()
+sub1Actor.SetMapper(sub1Mapper)
+
+sub2Mapper = vtk.vtkPointGaussianMapper()
+sub2Mapper.SetInputConnection(extract.GetOutputPort(2))
+sub2Mapper.EmissiveOff()
+sub2Mapper.SetScaleFactor(0.0)
+
+sub2Actor = vtk.vtkActor()
+sub2Actor.SetMapper(sub2Mapper)
+sub2Actor.AddPosition(0,-2.25,0)
+
+# Create the RenderWindow, Renderer and both Actors
+#
+ren0 = vtk.vtkRenderer()
+renWin = vtk.vtkRenderWindow()
+renWin.AddRenderer(ren0)
+iren = vtk.vtkRenderWindowInteractor()
+iren.SetRenderWindow(renWin)
+
+# Add the actors to the renderer, set the background and size
+#
+ren0.AddActor(subActor)
+ren0.AddActor(sub1Actor)
+ren0.AddActor(sub2Actor)
+ren0.SetBackground(0.1, 0.2, 0.4)
+
+renWin.SetSize(250,250)
+
+cam = ren0.GetActiveCamera()
+cam.SetFocalPoint(0,0,-1)
+cam.SetPosition(0,0,0)
+ren0.ResetCamera()
+
+iren.Initialize()
+
+# render the image
+#
+renWin.Render()
+
+#iren.Start()
diff --git a/Filters/Points/Testing/Python/TestPCACurvatureEstimation2.py b/Filters/Points/Testing/Python/TestPCACurvatureEstimation2.py
new file mode 100755
index 0000000000000000000000000000000000000000..568c08b95db5fd8e2c293aa51e70bd6862b1d494
--- /dev/null
+++ b/Filters/Points/Testing/Python/TestPCACurvatureEstimation2.py
@@ -0,0 +1,132 @@
+#!/usr/bin/env python
+import vtk
+from vtk.test import Testing
+from vtk.util.misc import vtkGetDataRoot
+VTK_DATA_ROOT = vtkGetDataRoot()
+
+# Interpolate onto a volume
+
+# Parameters for debugging
+NPts = 1000000
+math = vtk.vtkMath()
+math.RandomSeed(31415)
+
+# create pipeline
+#
+points = vtk.vtkBoundedPointSource()
+points.SetNumberOfPoints(NPts)
+points.SetBounds(-3,3, -1,1, -1,1)
+points.ProduceRandomScalarsOn()
+points.ProduceCellOutputOff()
+points.Update()
+
+# Create a cylinder
+cyl = vtk.vtkCylinder()
+cyl.SetCenter(-2,0,0)
+cyl.SetRadius(0.02)
+
+# Create a (thin) box implicit function
+box = vtk.vtkBox()
+box.SetBounds(-1,0.5, -0.5,0.5, -0.0005, 0.0005)
+
+# Create a sphere implicit function
+sphere = vtk.vtkSphere()
+sphere.SetCenter(2,0,0)
+sphere.SetRadius(0.8)
+
+# Boolean (union) these together
+imp = vtk.vtkImplicitBoolean()
+imp.SetOperationTypeToUnion()
+imp.AddFunction(cyl)
+imp.AddFunction(box)
+imp.AddFunction(sphere)
+
+# Extract points along sphere surface
+extract = vtk.vtkFitImplicitFunction()
+extract.SetInputConnection(points.GetOutputPort())
+extract.SetImplicitFunction(imp)
+extract.SetThreshold(0.0005)
+extract.Update()
+
+# Now generate normals from resulting points
+curv = vtk.vtkPCACurvatureEstimation()
+curv.SetInputConnection(extract.GetOutputPort())
+curv.SetSampleSize(6)
+
+# Time execution
+timer = vtk.vtkTimerLog()
+timer.StartTimer()
+curv.Update()
+timer.StopTimer()
+time = timer.GetElapsedTime()
+print("Points processed: {0}".format(NPts))
+print("   Time to generate curvature: {0}".format(time))
+
+# Break out the curvature into thress separate arrays
+assign = vtk.vtkAssignAttribute()
+assign.SetInputConnection(curv.GetOutputPort())
+assign.Assign("PCACurvature", "VECTORS", "POINT_DATA")
+
+extract = vtk.vtkExtractVectorComponents()
+extract.SetInputConnection(assign.GetOutputPort())
+extract.Update()
+print(extract.GetOutput(0).GetScalarRange())
+print(extract.GetOutput(1).GetScalarRange())
+print(extract.GetOutput(2).GetScalarRange())
+
+# Three different outputs for different curvatures
+subMapper = vtk.vtkPointGaussianMapper()
+subMapper.SetInputConnection(extract.GetOutputPort(0))
+subMapper.EmissiveOff()
+subMapper.SetScaleFactor(0.0)
+
+subActor = vtk.vtkActor()
+subActor.SetMapper(subMapper)
+subActor.AddPosition(0,2.25,0)
+
+sub1Mapper = vtk.vtkPointGaussianMapper()
+sub1Mapper.SetInputConnection(extract.GetOutputPort(1))
+sub1Mapper.EmissiveOff()
+sub1Mapper.SetScaleFactor(0.0)
+
+sub1Actor = vtk.vtkActor()
+sub1Actor.SetMapper(sub1Mapper)
+
+sub2Mapper = vtk.vtkPointGaussianMapper()
+sub2Mapper.SetInputConnection(extract.GetOutputPort(2))
+sub2Mapper.EmissiveOff()
+sub2Mapper.SetScaleFactor(0.0)
+
+sub2Actor = vtk.vtkActor()
+sub2Actor.SetMapper(sub2Mapper)
+sub2Actor.AddPosition(0,-2.25,0)
+
+# Create the RenderWindow, Renderer and both Actors
+#
+ren0 = vtk.vtkRenderer()
+renWin = vtk.vtkRenderWindow()
+renWin.AddRenderer(ren0)
+iren = vtk.vtkRenderWindowInteractor()
+iren.SetRenderWindow(renWin)
+
+# Add the actors to the renderer, set the background and size
+#
+ren0.AddActor(subActor)
+ren0.AddActor(sub1Actor)
+ren0.AddActor(sub2Actor)
+ren0.SetBackground(0.1, 0.2, 0.4)
+
+renWin.SetSize(250,250)
+
+cam = ren0.GetActiveCamera()
+cam.SetFocalPoint(0,0,-1)
+cam.SetPosition(0,0,0)
+ren0.ResetCamera()
+
+iren.Initialize()
+
+# render the image
+#
+renWin.Render()
+
+#iren.Start()
diff --git a/Filters/Points/Testing/Python/TestPCANormalEstimation.py b/Filters/Points/Testing/Python/TestPCANormalEstimation.py
new file mode 100755
index 0000000000000000000000000000000000000000..e5a8a021bc627e35fb9ff6e13441289e152e60d2
--- /dev/null
+++ b/Filters/Points/Testing/Python/TestPCANormalEstimation.py
@@ -0,0 +1,116 @@
+#!/usr/bin/env python
+import vtk
+from vtk.test import Testing
+from vtk.util.misc import vtkGetDataRoot
+VTK_DATA_ROOT = vtkGetDataRoot()
+
+# Interpolate onto a volume
+
+# Parameters for debugging
+NPts = 1000000
+math = vtk.vtkMath()
+math.RandomSeed(31415)
+
+# create pipeline
+#
+points = vtk.vtkBoundedPointSource()
+points.SetNumberOfPoints(NPts)
+points.ProduceRandomScalarsOn()
+points.ProduceCellOutputOff()
+points.Update()
+
+# Create a sphere implicit function
+sphere = vtk.vtkSphere()
+sphere.SetCenter(0,0,0)
+sphere.SetRadius(0.75)
+
+# Extract points along sphere surface
+extract = vtk.vtkFitImplicitFunction()
+extract.SetInputConnection(points.GetOutputPort())
+extract.SetImplicitFunction(sphere)
+extract.SetThreshold(0.005)
+extract.Update()
+
+# Now generate normals from resulting points
+norms = vtk.vtkPCANormalEstimation()
+norms.SetInputConnection(extract.GetOutputPort())
+norms.SetSampleSize(20)
+norms.FlipNormalsOn()
+norms.SetNormalOrientationToPoint()
+norms.SetOrientationPoint(0,0,0)
+
+# Time execution
+timer = vtk.vtkTimerLog()
+timer.StartTimer()
+norms.Update()
+timer.StopTimer()
+time = timer.GetElapsedTime()
+print("Points processed: {0}".format(NPts))
+print("   Time to generate normals: {0}".format(time))
+#print(hBin)
+#print(hBin.GetOutput())
+
+subMapper = vtk.vtkPointGaussianMapper()
+subMapper.SetInputConnection(norms.GetOutputPort())
+subMapper.EmissiveOff()
+subMapper.SetScaleFactor(0.0)
+
+subActor = vtk.vtkActor()
+subActor.SetMapper(subMapper)
+
+# Draw the normals
+mask = vtk.vtkMaskPoints()
+mask.SetInputConnection(norms.GetOutputPort())
+mask.SetRandomModeType(1)
+mask.SetMaximumNumberOfPoints(250)
+
+hhog = vtk.vtkHedgeHog()
+hhog.SetInputConnection(mask.GetOutputPort())
+hhog.SetVectorModeToUseNormal()
+hhog.SetScaleFactor(0.25)
+
+hogMapper = vtk.vtkPolyDataMapper()
+hogMapper.SetInputConnection(hhog.GetOutputPort())
+
+hogActor = vtk.vtkActor()
+hogActor.SetMapper(hogMapper)
+
+# Create an outline
+outline = vtk.vtkOutlineFilter()
+outline.SetInputConnection(points.GetOutputPort())
+
+outlineMapper = vtk.vtkPolyDataMapper()
+outlineMapper.SetInputConnection(outline.GetOutputPort())
+
+outlineActor = vtk.vtkActor()
+outlineActor.SetMapper(outlineMapper)
+
+# Create the RenderWindow, Renderer and both Actors
+#
+ren0 = vtk.vtkRenderer()
+renWin = vtk.vtkRenderWindow()
+renWin.AddRenderer(ren0)
+iren = vtk.vtkRenderWindowInteractor()
+iren.SetRenderWindow(renWin)
+
+# Add the actors to the renderer, set the background and size
+#
+ren0.AddActor(subActor)
+ren0.AddActor(hogActor)
+ren0.AddActor(outlineActor)
+ren0.SetBackground(0.1, 0.2, 0.4)
+
+renWin.SetSize(250,250)
+
+cam = ren0.GetActiveCamera()
+cam.SetFocalPoint(1,1,1)
+cam.SetPosition(0,0,0)
+ren0.ResetCamera()
+
+iren.Initialize()
+
+# render the image
+#
+renWin.Render()
+
+#iren.Start()
diff --git a/Filters/Points/Testing/Python/TestPCANormalEstimation2.py b/Filters/Points/Testing/Python/TestPCANormalEstimation2.py
new file mode 100755
index 0000000000000000000000000000000000000000..6c77b4684e339707107b20a0459fedfb824e7c00
--- /dev/null
+++ b/Filters/Points/Testing/Python/TestPCANormalEstimation2.py
@@ -0,0 +1,115 @@
+#!/usr/bin/env python
+import vtk
+from vtk.test import Testing
+from vtk.util.misc import vtkGetDataRoot
+VTK_DATA_ROOT = vtkGetDataRoot()
+
+# Interpolate onto a volume
+
+# Parameters for debugging
+NPts = 1000000
+math = vtk.vtkMath()
+math.RandomSeed(31415)
+
+# create pipeline
+#
+points = vtk.vtkBoundedPointSource()
+points.SetNumberOfPoints(NPts)
+points.ProduceRandomScalarsOn()
+points.ProduceCellOutputOff()
+points.Update()
+
+# Create a sphere implicit function
+sphere = vtk.vtkSphere()
+sphere.SetCenter(0,0,0)
+sphere.SetRadius(0.75)
+
+# Extract points along sphere surface
+extract = vtk.vtkFitImplicitFunction()
+extract.SetInputConnection(points.GetOutputPort())
+extract.SetImplicitFunction(sphere)
+extract.SetThreshold(0.005)
+extract.Update()
+
+# Now generate normals from resulting points
+norms = vtk.vtkPCANormalEstimation()
+norms.SetInputConnection(extract.GetOutputPort())
+norms.SetSampleSize(20)
+norms.FlipNormalsOn()
+norms.SetNormalOrientationToGraphTraversal()
+
+# Time execution
+timer = vtk.vtkTimerLog()
+timer.StartTimer()
+norms.Update()
+timer.StopTimer()
+time = timer.GetElapsedTime()
+print("Points processed: {0}".format(NPts))
+print("   Time to generate normals: {0}".format(time))
+#print(hBin)
+#print(hBin.GetOutput())
+
+subMapper = vtk.vtkPointGaussianMapper()
+subMapper.SetInputConnection(norms.GetOutputPort())
+subMapper.EmissiveOff()
+subMapper.SetScaleFactor(0.0)
+
+subActor = vtk.vtkActor()
+subActor.SetMapper(subMapper)
+
+# Draw the normals
+mask = vtk.vtkMaskPoints()
+mask.SetInputConnection(norms.GetOutputPort())
+mask.SetRandomModeType(1)
+mask.SetMaximumNumberOfPoints(250)
+
+hhog = vtk.vtkHedgeHog()
+hhog.SetInputConnection(mask.GetOutputPort())
+hhog.SetVectorModeToUseNormal()
+hhog.SetScaleFactor(0.25)
+
+hogMapper = vtk.vtkPolyDataMapper()
+hogMapper.SetInputConnection(hhog.GetOutputPort())
+
+hogActor = vtk.vtkActor()
+hogActor.SetMapper(hogMapper)
+
+# Create an outline
+outline = vtk.vtkOutlineFilter()
+outline.SetInputConnection(points.GetOutputPort())
+
+outlineMapper = vtk.vtkPolyDataMapper()
+outlineMapper.SetInputConnection(outline.GetOutputPort())
+
+outlineActor = vtk.vtkActor()
+outlineActor.SetMapper(outlineMapper)
+
+# Create the RenderWindow, Renderer and both Actors
+#
+ren0 = vtk.vtkRenderer()
+renWin = vtk.vtkRenderWindow()
+renWin.AddRenderer(ren0)
+iren = vtk.vtkRenderWindowInteractor()
+iren.SetRenderWindow(renWin)
+
+# Add the actors to the renderer, set the background and size
+#
+ren0.AddActor(subActor)
+ren0.AddActor(hogActor)
+ren0.AddActor(outlineActor)
+ren0.SetBackground(0.1, 0.2, 0.4)
+
+renWin.SetSize(250,250)
+
+cam = ren0.GetActiveCamera()
+cam.SetFocalPoint(1,1,1)
+cam.SetPosition(0,0,0)
+ren0.ResetCamera()
+
+iren.Initialize()
+
+# render the image
+#
+renWin.Render()
+
+#iren.Start()
diff --git a/Filters/Points/Testing/Python/TestRadiusOutlierRemoval.py b/Filters/Points/Testing/Python/TestRadiusOutlierRemoval.py
new file mode 100755
index 0000000000000000000000000000000000000000..100af2c3838cd20ac06e441358b8711bdfd628e8
--- /dev/null
+++ b/Filters/Points/Testing/Python/TestRadiusOutlierRemoval.py
@@ -0,0 +1,120 @@
+#!/usr/bin/env python
+import vtk
+from vtk.test import Testing
+from vtk.util.misc import vtkGetDataRoot
+VTK_DATA_ROOT = vtkGetDataRoot()
+
+# Interpolate onto a volume
+
+# Parameters for debugging
+NPts = 10000
+math = vtk.vtkMath()
+math.RandomSeed(31415)
+
+# create pipeline
+#
+points = vtk.vtkBoundedPointSource()
+points.SetNumberOfPoints(NPts)
+points.ProduceRandomScalarsOn()
+points.ProduceCellOutputOff()
+points.Update()
+
+# Reuse the locator
+locator = vtk.vtkStaticPointLocator()
+locator.SetDataSet(points.GetOutput())
+locator.BuildLocator()
+
+# Remove isolated points
+removal = vtk.vtkRadiusOutlierRemoval()
+removal.SetInputConnection(points.GetOutputPort())
+removal.SetLocator(locator)
+removal.SetRadius(0.1)
+removal.SetNumberOfNeighbors(2)
+removal.GenerateOutliersOn()
+
+# Time execution
+timer = vtk.vtkTimerLog()
+timer.StartTimer()
+removal.Update()
+timer.StopTimer()
+time = timer.GetElapsedTime()
+print("Time to remove points: {0}".format(time))
+print("   Number removed: {0}".format(removal.GetNumberOfPointsRemoved()),
+      " (out of: {}".format(NPts))
+
+# First output are the non-outliers
+remMapper = vtk.vtkPointGaussianMapper()
+remMapper.SetInputConnection(removal.GetOutputPort())
+remMapper.EmissiveOff()
+remMapper.SetScaleFactor(0.0)
+
+remActor = vtk.vtkActor()
+remActor.SetMapper(remMapper)
+
+# Create an outline
+outline = vtk.vtkOutlineFilter()
+outline.SetInputConnection(points.GetOutputPort())
+
+outlineMapper = vtk.vtkPolyDataMapper()
+outlineMapper.SetInputConnection(outline.GetOutputPort())
+
+outlineActor = vtk.vtkActor()
+outlineActor.SetMapper(outlineMapper)
+
+# Second output are the outliers
+remMapper1 = vtk.vtkPointGaussianMapper()
+remMapper1.SetInputConnection(removal.GetOutputPort(1))
+remMapper1.EmissiveOff()
+remMapper1.SetScaleFactor(0.0)
+
+remActor1 = vtk.vtkActor()
+remActor1.SetMapper(remMapper1)
+
+# Create an outline
+outline1 = vtk.vtkOutlineFilter()
+outline1.SetInputConnection(points.GetOutputPort())
+
+outlineMapper1 = vtk.vtkPolyDataMapper()
+outlineMapper1.SetInputConnection(outline1.GetOutputPort())
+
+outlineActor1 = vtk.vtkActor()
+outlineActor1.SetMapper(outlineMapper1)
+
+# Create the RenderWindow, Renderer and both Actors
+#
+ren0 = vtk.vtkRenderer()
+ren0.SetViewport(0,0,.5,1)
+ren1 = vtk.vtkRenderer()
+ren1.SetViewport(0.5,0,1,1)
+renWin = vtk.vtkRenderWindow()
+renWin.AddRenderer(ren0)
+renWin.AddRenderer(ren1)
+iren = vtk.vtkRenderWindowInteractor()
+iren.SetRenderWindow(renWin)
+
+# Add the actors to the renderer, set the background and size
+#
+ren0.AddActor(remActor)
+ren0.AddActor(outlineActor)
+ren0.SetBackground(0.1, 0.2, 0.4)
+
+ren1.AddActor(remActor1)
+ren1.AddActor(outlineActor1)
+ren1.SetBackground(0.1, 0.2, 0.4)
+
+renWin.SetSize(500,250)
+
+cam = ren0.GetActiveCamera()
+cam.SetFocalPoint(1,1,1)
+cam.SetPosition(0,0,0)
+ren0.ResetCamera()
+
+ren1.SetActiveCamera(cam)
+
+iren.Initialize()
+
+# render the image
+#
+renWin.Render()
+
+#iren.Start()
diff --git a/Filters/Points/Testing/Python/TestSignedDistanceFilter.py b/Filters/Points/Testing/Python/TestSignedDistanceFilter.py
new file mode 100755
index 0000000000000000000000000000000000000000..b08dc3ddac31850e734f2a17148c052a86f2e6d7
--- /dev/null
+++ b/Filters/Points/Testing/Python/TestSignedDistanceFilter.py
@@ -0,0 +1,128 @@
+#!/usr/bin/env python
+import vtk
+from vtk.test import Testing
+from vtk.util.misc import vtkGetDataRoot
+VTK_DATA_ROOT = vtkGetDataRoot()
+
+# Interpolate onto a volume
+
+# Parameters for debugging
+NPts = 1000000
+math = vtk.vtkMath()
+math.RandomSeed(31415)
+
+# create pipeline
+#
+points = vtk.vtkBoundedPointSource()
+points.SetNumberOfPoints(NPts)
+points.ProduceRandomScalarsOn()
+points.ProduceCellOutputOff()
+points.Update()
+
+# Create a sphere implicit function
+sphere = vtk.vtkSphere()
+sphere.SetCenter(0,0,0)
+sphere.SetRadius(0.75)
+
+# Cut the sphere in half with a plane
+plane = vtk.vtkPlane()
+plane.SetOrigin(0,0,0)
+plane.SetNormal(1,1,1)
+
+# Boolean (intersect) these together to create a hemi-sphere
+imp = vtk.vtkImplicitBoolean()
+imp.SetOperationTypeToIntersection()
+imp.AddFunction(sphere)
+imp.AddFunction(plane)
+
+# Extract points along hemi-sphere surface
+extract = vtk.vtkFitImplicitFunction()
+extract.SetInputConnection(points.GetOutputPort())
+extract.SetImplicitFunction(imp)
+extract.SetThreshold(0.005)
+extract.Update()
+
+# Now generate normals from resulting points
+norms = vtk.vtkPCANormalEstimation()
+norms.SetInputConnection(extract.GetOutputPort())
+norms.SetSampleSize(20)
+norms.FlipNormalsOff()
+norms.SetNormalOrientationToGraphTraversal()
+#norms.SetNormalOrientationToPoint()
+#norms.SetOrientationPoint(0.3,0.3,0.3)
+norms.Update()
+
+subMapper = vtk.vtkPointGaussianMapper()
+subMapper.SetInputConnection(extract.GetOutputPort())
+subMapper.EmissiveOff()
+subMapper.SetScaleFactor(0.0)
+
+subActor = vtk.vtkActor()
+subActor.SetMapper(subMapper)
+
+# Generate signed distance function and contour it
+dist = vtk.vtkSignedDistance()
+dist.SetInputConnection(norms.GetOutputPort())
+dist.SetRadius(0.1) #how far out to propagate distance calculation
+dist.SetBounds(-1,1, -1,1, -1,1)
+dist.SetDimensions(50,50,50)
+
+# Extract the surface with modified flying edges
+fe = vtk.vtkExtractSurface()
+fe.SetInputConnection(dist.GetOutputPort())
+fe.SetRadius(0.1) # this should match the signed distance radius
+
+# Time the execution
+timer = vtk.vtkTimerLog()
+timer.StartTimer()
+fe.Update()
+timer.StopTimer()
+time = timer.GetElapsedTime()
+print("Points processed: {0}".format(NPts))
+print("   Time to generate and extract distance function: {0}".format(time))
+
+feMapper = vtk.vtkPolyDataMapper()
+feMapper.SetInputConnection(fe.GetOutputPort())
+
+feActor = vtk.vtkActor()
+feActor.SetMapper(feMapper)
+
+# Create an outline
+outline = vtk.vtkOutlineFilter()
+outline.SetInputConnection(points.GetOutputPort())
+
+outlineMapper = vtk.vtkPolyDataMapper()
+outlineMapper.SetInputConnection(outline.GetOutputPort())
+
+outlineActor = vtk.vtkActor()
+outlineActor.SetMapper(outlineMapper)
+
+# Create the RenderWindow, Renderer and both Actors
+#
+ren0 = vtk.vtkRenderer()
+renWin = vtk.vtkRenderWindow()
+renWin.AddRenderer(ren0)
+iren = vtk.vtkRenderWindowInteractor()
+iren.SetRenderWindow(renWin)
+
+# Add the actors to the renderer, set the background and size
+#
+ren0.AddActor(subActor)
+ren0.AddActor(feActor)
+ren0.AddActor(outlineActor)
+ren0.SetBackground(0.1, 0.2, 0.4)
+
+renWin.SetSize(250,250)
+
+cam = ren0.GetActiveCamera()
+cam.SetFocalPoint(1,-1,-1)
+cam.SetPosition(0,0,0)
+ren0.ResetCamera()
+
+iren.Initialize()
+
+# render the image
+#
+renWin.Render()
+
+#iren.Start()
diff --git a/Filters/Points/Testing/Python/TestStatisticalOutlierRemoval.py b/Filters/Points/Testing/Python/TestStatisticalOutlierRemoval.py
new file mode 100755
index 0000000000000000000000000000000000000000..f4f4e41b775e78a21386ae14f4ee3ba08deae525
--- /dev/null
+++ b/Filters/Points/Testing/Python/TestStatisticalOutlierRemoval.py
@@ -0,0 +1,144 @@
+#!/usr/bin/env python
+import vtk
+from vtk.test import Testing
+from vtk.util.misc import vtkGetDataRoot
+VTK_DATA_ROOT = vtkGetDataRoot()
+
+# Interpolate onto a volume
+
+# Parameters for debugging
+NPts = 100000
+math = vtk.vtkMath()
+math.RandomSeed(31415)
+
+# create point cloud. A bunch of random points plus some outliers
+# over the six faces of the bounding box
+#
+points = vtk.vtkPoints()
+points.SetDataTypeToFloat()
+points.SetNumberOfPoints(NPts+6)
+scalars = vtk.vtkFloatArray()
+scalars.SetNumberOfTuples(NPts+6)
+scalars.SetName("scalars")
+for i in range(0,NPts):
+    points.SetPoint(i,math.Random(-1,1),math.Random(-1,1),math.Random(-1,1))
+    scalars.SetValue(i,math.Random(0,1))
+
+points.SetPoint(NPts,  -5,0,0)
+scalars.SetValue(NPts, 0.5)
+points.SetPoint(NPts+1, 5,0,0)
+scalars.SetValue(NPts+1, 0.5)
+points.SetPoint(NPts+2, 0,-5,0)
+scalars.SetValue(NPts+2, 0.5)
+points.SetPoint(NPts+3, 0, 5,0)
+scalars.SetValue(NPts+3, 0.5)
+points.SetPoint(NPts+4, 0,0,-5)
+scalars.SetValue(NPts+4, 0.5)
+points.SetPoint(NPts+5, 0,0, 5)
+scalars.SetValue(NPts+5, 0.5)
+
+polydata = vtk.vtkPolyData()
+polydata.SetPoints(points)
+polydata.GetPointData().SetScalars(scalars)
+
+# Reuse the locator
+locator = vtk.vtkStaticPointLocator()
+locator.SetDataSet(polydata)
+locator.BuildLocator()
+
+# Remove statistically isolated points
+removal = vtk.vtkStatisticalOutlierRemoval()
+removal.SetInputData(polydata)
+removal.SetLocator(locator)
+removal.SetSampleSize(20)
+removal.SetStandardDeviationFactor(1.5)
+removal.GenerateOutliersOn()
+
+# Time execution
+timer = vtk.vtkTimerLog()
+timer.StartTimer()
+removal.Update()
+timer.StopTimer()
+time = timer.GetElapsedTime()
+print("Number of points processed: {0}".format(NPts))
+print("   Time to remove outliers: {0}".format(time))
+print("   Number removed: {0}".format(removal.GetNumberOfPointsRemoved()))
+print("   Computed mean: {0}".format(removal.GetComputedMean()))
+print("   Computed standard deviation: {0}".format(removal.GetComputedStandardDeviation()))
+
+# First output are the non-outliers
+remMapper = vtk.vtkPointGaussianMapper()
+remMapper.SetInputConnection(removal.GetOutputPort())
+remMapper.EmissiveOff()
+remMapper.SetScaleFactor(0.0)
+
+remActor = vtk.vtkActor()
+remActor.SetMapper(remMapper)
+
+# Create an outline
+outline = vtk.vtkOutlineFilter()
+outline.SetInputData(polydata)
+
+outlineMapper = vtk.vtkPolyDataMapper()
+outlineMapper.SetInputConnection(outline.GetOutputPort())
+
+outlineActor = vtk.vtkActor()
+outlineActor.SetMapper(outlineMapper)
+
+# Second output are the outliers
+remMapper1 = vtk.vtkPointGaussianMapper()
+remMapper1.SetInputConnection(removal.GetOutputPort(1))
+remMapper1.EmissiveOff()
+remMapper1.SetScaleFactor(0.0)
+
+remActor1 = vtk.vtkActor()
+remActor1.SetMapper(remMapper1)
+
+# Create an outline
+outline1 = vtk.vtkOutlineFilter()
+outline1.SetInputData(polydata)
+
+outlineMapper1 = vtk.vtkPolyDataMapper()
+outlineMapper1.SetInputConnection(outline1.GetOutputPort())
+
+outlineActor1 = vtk.vtkActor()
+outlineActor1.SetMapper(outlineMapper1)
+
+# Create the RenderWindow, Renderer and both Actors
+#
+ren0 = vtk.vtkRenderer()
+ren0.SetViewport(0,0,.5,1)
+ren1 = vtk.vtkRenderer()
+ren1.SetViewport(0.5,0,1,1)
+renWin = vtk.vtkRenderWindow()
+renWin.AddRenderer(ren0)
+renWin.AddRenderer(ren1)
+iren = vtk.vtkRenderWindowInteractor()
+iren.SetRenderWindow(renWin)
+
+# Add the actors to the renderer, set the background and size
+#
+ren0.AddActor(remActor)
+ren0.AddActor(outlineActor)
+ren0.SetBackground(0.1, 0.2, 0.4)
+
+ren1.AddActor(remActor1)
+ren1.AddActor(outlineActor1)
+ren1.SetBackground(0.1, 0.2, 0.4)
+
+renWin.SetSize(500,250)
+
+cam = ren0.GetActiveCamera()
+cam.SetFocalPoint(1,1,1)
+cam.SetPosition(0,0,0)
+ren0.ResetCamera()
+
+ren1.SetActiveCamera(cam)
+
+iren.Initialize()
+
+# render the image
+#
+renWin.Render()
+
+#iren.Start()
diff --git a/Filters/Points/Testing/Python/TestVoxelGridFilter.py b/Filters/Points/Testing/Python/TestVoxelGridFilter.py
new file mode 100755
index 0000000000000000000000000000000000000000..8803ac7f5656d30060a2d26057a53435b4321be5
--- /dev/null
+++ b/Filters/Points/Testing/Python/TestVoxelGridFilter.py
@@ -0,0 +1,112 @@
+#!/usr/bin/env python
+import vtk
+from vtk.test import Testing
+from vtk.util.misc import vtkGetDataRoot
+VTK_DATA_ROOT = vtkGetDataRoot()
+
+# Interpolate onto a volume
+
+# Parameters for debugging
+NPts = 1000000
+math = vtk.vtkMath()
+math.RandomSeed(31415)
+
+# create pipeline
+#
+points = vtk.vtkBoundedPointSource()
+points.SetNumberOfPoints(NPts)
+points.ProduceRandomScalarsOn()
+points.ProduceCellOutputOff()
+points.Update()
+
+# Subsample
+subsample = vtk.vtkVoxelGrid()
+subsample.SetInputConnection(points.GetOutputPort())
+subsample.SetConfigurationStyleToAutomatic()
+
+# Time execution
+timer = vtk.vtkTimerLog()
+timer.StartTimer()
+subsample.Update()
+timer.StopTimer()
+time = timer.GetElapsedTime()
+print("Time to subsample: {0}".format(time))
+print("   Original number of points: {0}".format(NPts))
+print("   Final number of points: {0}".format(subsample.GetOutput().GetNumberOfPoints()))
+
+# Output the original points
+subMapper = vtk.vtkPointGaussianMapper()
+subMapper.SetInputConnection(points.GetOutputPort())
+subMapper.EmissiveOff()
+subMapper.SetScaleFactor(0.0)
+
+subActor = vtk.vtkActor()
+subActor.SetMapper(subMapper)
+
+# Create an outline
+outline = vtk.vtkOutlineFilter()
+outline.SetInputConnection(points.GetOutputPort())
+
+outlineMapper = vtk.vtkPolyDataMapper()
+outlineMapper.SetInputConnection(outline.GetOutputPort())
+
+outlineActor = vtk.vtkActor()
+outlineActor.SetMapper(outlineMapper)
+
+# Output the subsampled points
+subMapper1 = vtk.vtkPointGaussianMapper()
+subMapper1.SetInputConnection(subsample.GetOutputPort())
+subMapper1.EmissiveOff()
+subMapper1.SetScaleFactor(0.0)
+
+subActor1 = vtk.vtkActor()
+subActor1.SetMapper(subMapper1)
+
+# Create an outline
+outline1 = vtk.vtkOutlineFilter()
+outline1.SetInputConnection(points.GetOutputPort())
+
+outlineMapper1 = vtk.vtkPolyDataMapper()
+outlineMapper1.SetInputConnection(outline1.GetOutputPort())
+
+outlineActor1 = vtk.vtkActor()
+outlineActor1.SetMapper(outlineMapper1)
+
+# Create the RenderWindow, Renderer and both Actors
+#
+ren0 = vtk.vtkRenderer()
+ren0.SetViewport(0,0,.5,1)
+ren1 = vtk.vtkRenderer()
+ren1.SetViewport(0.5,0,1,1)
+renWin = vtk.vtkRenderWindow()
+renWin.AddRenderer(ren0)
+renWin.AddRenderer(ren1)
+iren = vtk.vtkRenderWindowInteractor()
+iren.SetRenderWindow(renWin)
+
+# Add the actors to the renderer, set the background and size
+#
+ren0.AddActor(subActor)
+ren0.AddActor(outlineActor)
+ren0.SetBackground(0.1, 0.2, 0.4)
+
+ren1.AddActor(subActor1)
+ren1.AddActor(outlineActor1)
+ren1.SetBackground(0.1, 0.2, 0.4)
+
+renWin.SetSize(500,250)
+
+cam = ren0.GetActiveCamera()
+cam.SetFocalPoint(0,0,0)
+cam.SetPosition(1,1,1)
+ren0.ResetCamera()
+
+ren1.SetActiveCamera(cam)
+
+iren.Initialize()
+
+# render the image
+#
+renWin.Render()
+
+#iren.Start()
diff --git a/Filters/Points/vtkBoundedPointSource.cxx b/Filters/Points/vtkBoundedPointSource.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..d3ea7a1964ffef1674bc14ab741e9304f4fd05b2
--- /dev/null
+++ b/Filters/Points/vtkBoundedPointSource.cxx
@@ -0,0 +1,154 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkBoundedPointSource.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.
+
+=========================================================================*/
+#include "vtkBoundedPointSource.h"
+
+#include "vtkCellArray.h"
+#include "vtkMath.h"
+#include "vtkInformation.h"
+#include "vtkInformationVector.h"
+#include "vtkObjectFactory.h"
+#include "vtkPoints.h"
+#include "vtkPolyData.h"
+#include "vtkFloatArray.h"
+#include "vtkPointData.h"
+
+vtkStandardNewMacro(vtkBoundedPointSource);
+
+//----------------------------------------------------------------------------
+vtkBoundedPointSource::vtkBoundedPointSource()
+{
+  this->NumberOfPoints = 100;
+
+  this->Bounds[0] = this->Bounds[2] = this->Bounds[4] = -1.0;
+  this->Bounds[1] = this->Bounds[3] = this->Bounds[5] = 1.0;
+
+  this->OutputPointsPrecision = SINGLE_PRECISION;
+
+  this->ProduceCellOutput = false;
+
+  this->ProduceRandomScalars = false;
+  this->ScalarRange[0] = 0.0;
+  this->ScalarRange[1] = 1.0;
+
+  this->SetNumberOfInputPorts(0);
+}
+
+//----------------------------------------------------------------------------
+int vtkBoundedPointSource::RequestData(
+  vtkInformation *vtkNotUsed(request),
+  vtkInformationVector **vtkNotUsed(inputVector),
+  vtkInformationVector *outputVector)
+{
+  // get the info object
+  vtkInformation *outInfo = outputVector->GetInformationObject(0);
+
+  // get the ouptut
+  vtkPolyData *output = vtkPolyData::SafeDownCast(
+    outInfo->Get(vtkDataObject::DATA_OBJECT()));
+
+  vtkIdType ptId;
+  double x[3];
+
+  vtkPoints *newPoints = vtkPoints::New();
+  // Set the desired precision for the points in the output.
+  if(this->OutputPointsPrecision == vtkAlgorithm::DOUBLE_PRECISION)
+    {
+    newPoints->SetDataType(VTK_DOUBLE);
+    }
+  else
+    {
+    newPoints->SetDataType(VTK_FLOAT);
+    }
+
+  // Generate the points
+  newPoints->SetNumberOfPoints(this->NumberOfPoints);
+  double xmin = (this->Bounds[0] < this->Bounds[1] ? this->Bounds[0] : this->Bounds[1]);
+  double xmax = (this->Bounds[0] < this->Bounds[1] ? this->Bounds[1] : this->Bounds[0]);
+  double ymin = (this->Bounds[2] < this->Bounds[3] ? this->Bounds[2] : this->Bounds[3]);
+  double ymax = (this->Bounds[2] < this->Bounds[3] ? this->Bounds[3] : this->Bounds[2]);
+  double zmin = (this->Bounds[4] < this->Bounds[5] ? this->Bounds[4] : this->Bounds[5]);
+  double zmax = (this->Bounds[4] < this->Bounds[5] ? this->Bounds[5] : this->Bounds[4]);
+
+  vtkMath *math = vtkMath::New();
+  for (ptId=0; ptId<this->NumberOfPoints; ptId++)
+    {
+    x[0] = math->Random(xmin,xmax);
+    x[1] = math->Random(ymin,ymax);
+    x[2] = math->Random(zmin,zmax);
+    newPoints->SetPoint(ptId,x);
+    }
+  output->SetPoints(newPoints);
+  newPoints->Delete();
+
+  // Generate the scalars if requested
+  if ( this->ProduceRandomScalars )
+    {
+    vtkFloatArray *scalars = vtkFloatArray::New();
+    scalars->SetName("RandomScalars");
+    scalars->SetNumberOfTuples(this->NumberOfPoints);
+    float *s = static_cast<float*>(scalars->GetVoidPointer(0));
+    double sMin = (this->ScalarRange[0] < this->ScalarRange[1] ?
+                   this->ScalarRange[0] : this->ScalarRange[1]);
+    double sMax = (this->ScalarRange[0] < this->ScalarRange[1] ?
+                   this->ScalarRange[1] : this->ScalarRange[0]);
+    for (ptId=0; ptId<this->NumberOfPoints; ptId++)
+      {
+      *s++ = math->Random(sMin,sMax);
+      }
+    output->GetPointData()->SetScalars(scalars);
+    scalars->Delete();
+    }
+
+  // Generate the vertices if requested
+  if ( this->ProduceCellOutput )
+    {
+    vtkCellArray *newVerts = vtkCellArray::New();
+    newVerts->Allocate(newVerts->EstimateSize(1,this->NumberOfPoints));
+    newVerts->InsertNextCell(this->NumberOfPoints);
+    for (ptId=0; ptId<this->NumberOfPoints; ptId++)
+      {
+      newVerts->InsertCellPoint(ptId);
+      }
+    output->SetVerts(newVerts);
+    newVerts->Delete();
+    }
+
+  math->Delete();
+  return 1;
+}
+
+//----------------------------------------------------------------------------
+void vtkBoundedPointSource::PrintSelf(ostream& os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os,indent);
+
+  os << indent << "Number Of Points: " << this->NumberOfPoints << "\n";
+
+  for(int i=0;i<6;i++)
+    {
+    os << indent << "Bounds[" << i << "]: " << this->Bounds[i] << "\n";
+    }
+
+  os << indent << "Output Points Precision: " << this->OutputPointsPrecision << "\n";
+
+  os << indent << "Produce Cell Output: "
+     << (this->ProduceCellOutput ? "On\n" : "Off\n");
+
+  os << indent << "Produce Random Scalars: "
+     << (this->ProduceRandomScalars ? "On\n" : "Off\n");
+  os << indent << "Scalar Range (" << this->ScalarRange[0] << ","
+     << this->ScalarRange[1] << ")\n";
+
+}
diff --git a/Filters/Points/vtkBoundedPointSource.h b/Filters/Points/vtkBoundedPointSource.h
new file mode 100644
index 0000000000000000000000000000000000000000..271533ff7b745ef0ebec0b54bd3b1368daeb3e29
--- /dev/null
+++ b/Filters/Points/vtkBoundedPointSource.h
@@ -0,0 +1,98 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkBoundedPointSource.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.
+
+=========================================================================*/
+// .NAME vtkBoundedPointSource - create a random cloud of points within a
+// specified bounding box
+
+// .SECTION Description
+// vtkBoundedPointSource is a source object that creates a user-specified
+// number of points within a specified bounding box. The points are scattered
+// randomly throughout the box. Optionally, the user can produce a
+// vtkPolyVertex cell as well as random scalar values within a specified
+// range. The class is typically used for debugging and testing, as well as
+// seeding streamlines.
+
+#ifndef vtkBoundedPointSource_h
+#define vtkBoundedPointSource_h
+
+#include "vtkFiltersPointsModule.h" // For export macro
+#include "vtkPolyDataAlgorithm.h"
+
+class VTKFILTERSPOINTS_EXPORT vtkBoundedPointSource : public vtkPolyDataAlgorithm
+{
+public:
+  // Description:
+  // Standard methods for instantiation, type information and printing.
+  static vtkBoundedPointSource *New();
+  vtkTypeMacro(vtkBoundedPointSource,vtkPolyDataAlgorithm);
+  void PrintSelf(ostream& os, vtkIndent indent);
+
+  // Description:
+  // Set the number of points to generate.
+  vtkSetClampMacro(NumberOfPoints,vtkIdType,1,VTK_ID_MAX);
+  vtkGetMacro(NumberOfPoints,vtkIdType);
+
+  // Description:
+  // Set the bounding box for the point distribution. By default the bounds is
+  // (-1,1,-1,1,-1,1).
+  vtkSetVector6Macro(Bounds,double);
+  vtkGetVectorMacro(Bounds,double,6);
+
+  // Description:
+  // Set/get the desired precision for the output points.
+  // vtkAlgorithm::SINGLE_PRECISION - Output single-precision floating point.
+  // vtkAlgorithm::DOUBLE_PRECISION - Output double-precision floating point.
+  vtkSetMacro(OutputPointsPrecision,int);
+  vtkGetMacro(OutputPointsPrecision,int);
+
+  // Description:
+  // Indicate whether to produce a vtkPolyVertex cell to go along with the
+  // output vtkPoints generated. By default a cell is NOT produced. Some filters
+  // do not need the vtkPolyVertex which just consumes a lot of memory.
+  vtkSetMacro(ProduceCellOutput, bool);
+  vtkGetMacro(ProduceCellOutput, bool);
+  vtkBooleanMacro(ProduceCellOutput, bool);
+
+  // Description:
+  // Indicate whether to produce random point scalars in the output. By default
+  // this is off.
+  vtkSetMacro(ProduceRandomScalars, bool);
+  vtkGetMacro(ProduceRandomScalars, bool);
+  vtkBooleanMacro(ProduceRandomScalars, bool);
+
+  // Description:
+  // Set the range in which the random scalars should be produced. By default the
+  // scalar range is (0,1).
+  vtkSetVector2Macro(ScalarRange,double);
+  vtkGetVectorMacro(ScalarRange,double,2);
+
+protected:
+  vtkBoundedPointSource();
+  ~vtkBoundedPointSource() {}
+
+  int RequestData(vtkInformation *, vtkInformationVector **, vtkInformationVector *);
+
+  vtkIdType NumberOfPoints;
+  double Bounds[6];
+  int OutputPointsPrecision;
+  bool ProduceCellOutput;
+  bool ProduceRandomScalars;
+  double ScalarRange[2];
+
+private:
+  vtkBoundedPointSource(const vtkBoundedPointSource&) VTK_DELETE_FUNCTION;
+  void operator=(const vtkBoundedPointSource&) VTK_DELETE_FUNCTION;
+};
+
+#endif
diff --git a/Filters/Points/vtkEuclideanClusterExtraction.cxx b/Filters/Points/vtkEuclideanClusterExtraction.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..4b3252287e6d24ee45abd5ac51c9b8d245262750
--- /dev/null
+++ b/Filters/Points/vtkEuclideanClusterExtraction.cxx
@@ -0,0 +1,463 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkEuclideanClusterExtraction.cxx
+
+  Copyright (c) Kitware, Inc.
+  All rights reserved.
+  See LICENSE file 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.
+
+=========================================================================*/
+#include "vtkEuclideanClusterExtraction.h"
+
+#include "vtkPointSet.h"
+#include "vtkIdList.h"
+#include "vtkInformation.h"
+#include "vtkInformationVector.h"
+#include "vtkMath.h"
+#include "vtkObjectFactory.h"
+#include "vtkPointData.h"
+#include "vtkPoints.h"
+#include "vtkFloatArray.h"
+#include "vtkAbstractPointLocator.h"
+#include "vtkStaticPointLocator.h"
+#include "vtkIdTypeArray.h"
+
+vtkStandardNewMacro(vtkEuclideanClusterExtraction);
+vtkCxxSetObjectMacro(vtkEuclideanClusterExtraction,Locator,vtkAbstractPointLocator);
+
+//----------------------------------------------------------------------------
+// Construct with default extraction mode to extract largest cluster.
+vtkEuclideanClusterExtraction::vtkEuclideanClusterExtraction()
+{
+  this->ClusterSizes = vtkIdTypeArray::New();
+  this->ExtractionMode = VTK_EXTRACT_LARGEST_CLUSTER;
+  this->ColorClusters = false;
+
+  this->ScalarConnectivity = false;
+  this->ScalarRange[0] = 0.0;
+  this->ScalarRange[1] = 1.0;
+
+  this->ClosestPoint[0] = this->ClosestPoint[1] = this->ClosestPoint[2] = 0.0;
+
+  this->Locator = vtkStaticPointLocator::New();
+
+  this->NeighborScalars = vtkFloatArray::New();
+  this->NeighborScalars->Allocate(64);
+
+  this->NeighborPointIds = vtkIdList::New();
+  this->NeighborPointIds->Allocate(64);
+
+  this->Seeds = vtkIdList::New();
+  this->SpecifiedClusterIds = vtkIdList::New();
+
+  this->NewScalars = 0;
+
+}
+
+//----------------------------------------------------------------------------
+vtkEuclideanClusterExtraction::~vtkEuclideanClusterExtraction()
+{
+  this->SetLocator(NULL);
+  this->ClusterSizes->Delete();
+  this->NeighborScalars->Delete();
+  this->NeighborPointIds->Delete();
+  this->Seeds->Delete();
+  this->SpecifiedClusterIds->Delete();
+}
+
+//----------------------------------------------------------------------------
+int vtkEuclideanClusterExtraction::RequestData(
+  vtkInformation *vtkNotUsed(request),
+  vtkInformationVector **inputVector,
+  vtkInformationVector *outputVector)
+{
+  // get the info objects
+  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
+  vtkInformation *outInfo = outputVector->GetInformationObject(0);
+
+  // get the input and output
+  vtkPointSet *input = vtkPointSet::SafeDownCast(
+    inInfo->Get(vtkDataObject::DATA_OBJECT()));
+  vtkPolyData *output = vtkPolyData::SafeDownCast(
+    outInfo->Get(vtkDataObject::DATA_OBJECT()));
+
+  vtkIdType numPts, i, ptId;
+  vtkPoints *newPts;
+  int maxPointsInCluster, clusterId, largestClusterId=0;
+  vtkPointData *pd=input->GetPointData(), *outputPD=output->GetPointData();
+
+  vtkDebugMacro(<<"Executing point clustering filter.");
+
+  //  Check input/allocate storage
+  //
+  if ( (numPts=input->GetNumberOfPoints()) < 1 )
+    {
+    vtkDebugMacro(<<"No data to cluster!");
+    return 1;
+    }
+  vtkPoints *inPts = input->GetPoints();
+
+  // Need to build a locator
+  if ( !this->Locator )
+    {
+    vtkErrorMacro(<<"Point locator required\n");
+    return 0;
+    }
+  this->Locator->SetDataSet(input);
+  this->Locator->BuildLocator();
+
+  // See whether to consider scalar connectivity
+  //
+  this->InScalars = input->GetPointData()->GetScalars();
+  if ( !this->ScalarConnectivity )
+    {
+    this->InScalars = NULL;
+    }
+  else
+    {
+    this->NeighborScalars->SetNumberOfComponents(this->InScalars->GetNumberOfComponents());
+    if ( this->ScalarRange[1] < this->ScalarRange[0] )
+      {
+      this->ScalarRange[1] = this->ScalarRange[0];
+      }
+    }
+
+  // Initialize.  Keep track of the points visited.
+  //
+  this->Visited = new char [numPts];
+  std::fill_n(this->Visited, numPts, static_cast<char>(0));
+
+  this->ClusterSizes->Reset();
+  this->PointMap = new vtkIdType[numPts];
+  std::fill_n(this->PointMap, numPts, static_cast<vtkIdType>(-1));
+
+  this->NewScalars = vtkIdTypeArray::New();
+  this->NewScalars->SetName("ClusterId");
+  this->NewScalars->SetNumberOfTuples(numPts);
+
+  newPts = vtkPoints::New();
+  newPts->SetDataType(input->GetPoints()->GetDataType());
+  newPts->Allocate(numPts);
+
+  // Traverse all points marking those visited.  Each new search
+  // starts a new connected cluster. Connected clusters grow
+  // using a connected wave propagation.
+  //
+  this->Wave = vtkIdList::New();
+  this->Wave->Allocate(numPts/4+1,numPts);
+  this->Wave2 = vtkIdList::New();
+  this->Wave2->Allocate(numPts/4+1,numPts);
+
+  this->PointNumber = 0;
+  this->ClusterNumber = 0;
+  maxPointsInCluster = 0;
+
+  this->PointIds = vtkIdList::New();
+  this->PointIds->Allocate(8, VTK_CELL_SIZE);
+
+  if ( this->ExtractionMode != VTK_EXTRACT_POINT_SEEDED_CLUSTERS &&
+  this->ExtractionMode != VTK_EXTRACT_CLOSEST_POINT_CLUSTER )
+    { //visit all points assigning cluster number
+    for (ptId=0; ptId < numPts; ptId++)
+      {
+      if ( ptId && !(ptId % 10000) )
+        {
+        this->UpdateProgress (0.1 + 0.8*ptId/numPts);
+        }
+
+      if ( ! this->Visited[ptId] )
+        {
+        this->NumPointsInCluster = 0;
+        this->InsertIntoWave(this->Wave,ptId);
+        this->TraverseAndMark (inPts);
+
+        if ( this->NumPointsInCluster > maxPointsInCluster )
+          {
+          maxPointsInCluster = this->NumPointsInCluster;
+          largestClusterId = this->ClusterNumber;
+          }
+
+        if ( this->NumPointsInCluster > 0 )
+          {
+          this->ClusterSizes->InsertValue(this->ClusterNumber++,
+                                          this->NumPointsInCluster);
+          }
+        this->Wave->Reset();
+        this->Wave2->Reset();
+        }
+      }
+    }
+  else // clusters have been seeded, everything considered in same cluster
+    {
+    this->NumPointsInCluster = 0;
+
+    if ( this->ExtractionMode == VTK_EXTRACT_POINT_SEEDED_CLUSTERS )
+      {
+      this->NumPointsInCluster = 0;
+      for (i=0; i < this->Seeds->GetNumberOfIds(); i++)
+        {
+        ptId = this->Seeds->GetId(i);
+        if ( ptId >= 0 )
+          {
+          this->InsertIntoWave(this->Wave,ptId);
+          }
+        }
+      }
+    else if ( this->ExtractionMode == VTK_EXTRACT_CLOSEST_POINT_CLUSTER )
+      {//loop over points, find closest one
+      ptId = this->Locator->FindClosestPoint(this->ClosestPoint);
+      this->InsertIntoWave(this->Wave,ptId);
+      }
+    this->UpdateProgress (0.5);
+
+    //mark all seeded clusters
+    this->TraverseAndMark (inPts);
+    this->ClusterSizes->InsertValue(this->ClusterNumber,this->NumPointsInCluster);
+    this->UpdateProgress (0.9);
+    }
+
+  vtkDebugMacro (<<"Extracted " << this->ClusterNumber << " cluster(s)");
+  this->Wave->Delete();
+  this->Wave2->Delete();
+  delete [] this->Visited;
+
+  // Now that points have been marked, traverse the PointMap pulling
+  // everything that has been visited and is selected for output.
+  outputPD->CopyAllocate(pd);
+  if ( this->ExtractionMode == VTK_EXTRACT_POINT_SEEDED_CLUSTERS ||
+  this->ExtractionMode == VTK_EXTRACT_CLOSEST_POINT_CLUSTER ||
+  this->ExtractionMode == VTK_EXTRACT_ALL_CLUSTERS)
+    { // extract any point that's been visited
+    for (ptId=0; ptId < numPts; ptId++)
+      {
+      if ( this->PointMap[ptId] >= 0 )
+        {
+        newPts->InsertPoint(this->PointMap[ptId],inPts->GetPoint(ptId));
+        outputPD->CopyData(pd,ptId,this->PointMap[ptId]);
+        }
+      }
+    }
+  else if ( this->ExtractionMode == VTK_EXTRACT_SPECIFIED_CLUSTERS )
+    {
+    bool inCluster;
+    for (ptId=0; ptId < numPts; ptId++)
+      {
+      if ( this->PointMap[ptId] >= 0 )
+        {
+        clusterId = this->NewScalars->GetValue(this->PointMap[ptId]);
+        for (inCluster=false,i=0; i<this->SpecifiedClusterIds->GetNumberOfIds(); i++)
+          {
+          if ( clusterId == this->SpecifiedClusterIds->GetId(i) )
+            {
+            inCluster = true;
+            break;
+            }
+          }
+        if ( inCluster )
+          {
+          newPts->InsertPoint(this->PointMap[ptId],inPts->GetPoint(ptId));
+          outputPD->CopyData(pd,ptId,this->PointMap[ptId]);
+          }
+        }
+      }
+    }
+  else //extract largest cluster
+    {
+    for (ptId=0; ptId < numPts; ptId++)
+      {
+      if ( this->PointMap[ptId] >= 0 )
+        {
+        clusterId = this->NewScalars->GetValue(this->PointMap[ptId]);
+        if ( clusterId == largestClusterId )
+          {
+          newPts->InsertPoint(this->PointMap[ptId],inPts->GetPoint(ptId));
+          outputPD->CopyData(pd,ptId,this->PointMap[ptId]);
+          }
+        }
+      }
+    }
+
+  // if coloring clusters; send down new scalar data
+  if ( this->ColorClusters )
+    {
+    int idx = outputPD->AddArray(this->NewScalars);
+    outputPD->SetActiveAttribute(idx, vtkDataSetAttributes::SCALARS);
+    }
+  this->NewScalars->Delete();
+
+  newPts->Squeeze();
+  output->SetPoints(newPts);
+
+  delete [] this->PointMap;
+  this->PointIds->Delete();
+
+  // print out some debugging information
+  int num = this->GetNumberOfExtractedClusters();
+  int count = 0;
+
+  for (int ii = 0; ii < num; ii++)
+    {
+    count += this->ClusterSizes->GetValue (ii);
+    }
+  vtkDebugMacro (<< "Total # of points accounted for: " << count);
+  vtkDebugMacro (<< "Extracted " << newPts->GetNumberOfPoints() << " points");
+  newPts->Delete();
+
+  return 1;
+}
+
+
+//----------------------------------------------------------------------------
+// Insert point into connected wave. Check to make sure it satisfies connectivity
+// criterion (if enabled).
+void vtkEuclideanClusterExtraction::
+InsertIntoWave(vtkIdList *wave, vtkIdType ptId)
+{
+  this->Visited[ptId] = 1;
+  if ( this->InScalars ) //is scalar connectivity enabled?
+    {
+    double s = this->InScalars->GetTuple1(ptId);
+    if ( s >= this->ScalarRange[0] && s <= this->ScalarRange[1] )
+      {
+      wave->InsertNextId(ptId);
+      }
+    }
+  else
+    {
+    wave->InsertNextId(ptId);
+    }
+}
+
+
+//----------------------------------------------------------------------------
+// Update current point information including updating cluster number.  Note:
+// traversal occurs across proximally located points, possibly limited by
+// scalar connectivty.
+//
+void vtkEuclideanClusterExtraction::TraverseAndMark (vtkPoints *inPts)
+{
+  vtkIdType i, j, numPts, numIds, ptId;
+  vtkIdList *tmpWave;
+  double x[3];
+
+  while ( (numIds=this->Wave->GetNumberOfIds()) > 0 )
+    {
+    for ( i=0; i < numIds; i++ ) //for all points in this wave
+      {
+      ptId = this->Wave->GetId(i);
+      this->PointMap[ptId] = this->PointNumber++;
+      this->NewScalars->SetValue(this->PointMap[ptId],this->ClusterNumber);
+      this->NumPointsInCluster++;
+
+      inPts->GetPoint(ptId,x);
+      this->Locator->FindPointsWithinRadius(this->Radius,x,this->NeighborPointIds);
+
+      numPts = this->NeighborPointIds->GetNumberOfIds();
+      for (j=0; j < numPts; ++j)
+        {
+        ptId = this->NeighborPointIds->GetId(j);
+        if ( ! this->Visited[ptId] )
+          {
+          this->InsertIntoWave(this->Wave2,ptId);
+          }//if point not yet visited
+        }//for all neighbors
+      }//for all cells in this connected wave
+
+    tmpWave = this->Wave;
+    this->Wave = this->Wave2;
+    this->Wave2 = tmpWave;
+    tmpWave->Reset();
+    } //while wave is not empty
+
+  return;
+}
+
+//----------------------------------------------------------------------------
+// Obtain the number of connected clusters.
+int vtkEuclideanClusterExtraction::GetNumberOfExtractedClusters()
+{
+  return this->ClusterSizes->GetMaxId() + 1;
+}
+
+//----------------------------------------------------------------------------
+// Initialize list of point ids used to seed clusters.
+void vtkEuclideanClusterExtraction::InitializeSeedList()
+{
+  this->Modified();
+  this->Seeds->Reset();
+}
+
+//----------------------------------------------------------------------------
+// Add a seed id. Note: ids are 0-offset.
+void vtkEuclideanClusterExtraction::AddSeed(vtkIdType id)
+{
+  this->Modified();
+  this->Seeds->InsertNextId(id);
+}
+
+//----------------------------------------------------------------------------
+// Delete a seed id. Note: ids are 0-offset.
+void vtkEuclideanClusterExtraction::DeleteSeed(vtkIdType id)
+{
+  this->Modified();
+  this->Seeds->DeleteId(id);
+}
+
+//----------------------------------------------------------------------------
+// Initialize list of cluster ids to extract.
+void vtkEuclideanClusterExtraction::InitializeSpecifiedClusterList()
+{
+  this->Modified();
+  this->SpecifiedClusterIds->Reset();
+}
+
+//----------------------------------------------------------------------------
+// Add a cluster id to extract. Note: ids are 0-offset.
+void vtkEuclideanClusterExtraction::AddSpecifiedCluster(int id)
+{
+  this->Modified();
+  this->SpecifiedClusterIds->InsertNextId(id);
+}
+
+//----------------------------------------------------------------------------
+// Delete a cluster id to extract. Note: ids are 0-offset.
+void vtkEuclideanClusterExtraction::DeleteSpecifiedCluster(int id)
+{
+  this->Modified();
+  this->SpecifiedClusterIds->DeleteId(id);
+}
+
+//----------------------------------------------------------------------------
+int vtkEuclideanClusterExtraction::
+FillInputPortInformation(int, vtkInformation *info)
+{
+  info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkPointSet");
+  return 1;
+}
+
+//----------------------------------------------------------------------------
+void vtkEuclideanClusterExtraction::PrintSelf(ostream& os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os,indent);
+
+  os << indent << "Extraction Mode: ";
+  os << this->GetExtractionModeAsString() << "\n";
+
+  os << indent << "Closest Point: (" << this->ClosestPoint[0] << ", "
+     << this->ClosestPoint[1] << ", " << this->ClosestPoint[2] << ")\n";
+
+  os << indent << "Color Clusters: " << (this->ColorClusters ? "On\n" : "Off\n");
+
+  os << indent << "Scalar Connectivity: "
+     << (this->ScalarConnectivity ? "On\n" : "Off\n");
+
+  double *range = this->GetScalarRange();
+  os << indent << "Scalar Range: (" << range[0] << ", " << range[1] << ")\n";
+
+  os << indent << "Locator: " << this->Locator << "\n";
+}
diff --git a/Filters/Points/vtkEuclideanClusterExtraction.h b/Filters/Points/vtkEuclideanClusterExtraction.h
new file mode 100644
index 0000000000000000000000000000000000000000..35fe8ebd50c9b379b6f738c3a6379d72c33063cb
--- /dev/null
+++ b/Filters/Points/vtkEuclideanClusterExtraction.h
@@ -0,0 +1,233 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkEuclideanClusterExtraction.h
+
+  Copyright (c) Kitware, Inc.
+  All rights reserved.
+  See LICENSE file 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.
+
+=========================================================================*/
+// .NAME vtkEuclideanClusterExtraction - perform segmentation based on geometric
+// proximity and optional scalar threshold
+// .SECTION Description
+// vtkEuclideanClusterExtraction is a filter that extracts points that are in
+// close geometric proximity, and optionally satisfies a scalar threshold
+// criterion. (Points extracted in this way are referred to as clusters.)
+// The filter works in one of five ways: 1) extract the largest cluster in the
+// dataset; 2) extract specified cluster number(s); 3) extract all clusters
+// containing specified point ids; 4) extract the cluster closest to a specified
+// point; or 5) extract all clusters (which can be used for coloring the clusters).
+//
+// Note that geometric proximity is defined by setting the Radius instance
+// variable. This variable defines a local sphere around each point; other
+// points contained in this sphere are considered "connected" to the
+// point. Setting this number too large will connect clusters that should not
+// be; setting it too small will fragment the point cloud into myriad
+// clusters. To accelerate the geometric proximity operations, a point
+// locator may be specified. By default, a vtkStaticPointLocator is used, but
+// any vtkAbstractPointLocator may be specified.
+//
+// The behavior of vtkEuclideanClusterExtraction can be modified by turning
+// on the boolean ivar ScalarConnectivity. If this flag is on, the clustering
+// algorithm is modified so that points are considered part of a cluster if
+// they satisfy both the geometric proximity measure, and the points scalar
+// values falls into the scalar range specified. This use of
+// ScalarConnectivity is particularly useful for data with intensity or color
+// information, serving as a simple "connected segmentation" algorithm. For
+// example, by using a seed point in a known cluster, clustering will pull
+// out all points "representing" the local structure.
+
+// .SECTION See Also
+// vtkConnectivityFilter vtkPolyDataConnectivityFilter
+
+#ifndef vtkEuclideanClusterExtraction_h
+#define vtkEuclideanClusterExtraction_h
+
+#include "vtkFiltersPointsModule.h" // For export macro
+#include "vtkPolyDataAlgorithm.h"
+
+#define VTK_EXTRACT_POINT_SEEDED_CLUSTERS 1
+#define VTK_EXTRACT_SPECIFIED_CLUSTERS 2
+#define VTK_EXTRACT_LARGEST_CLUSTER 3
+#define VTK_EXTRACT_ALL_CLUSTERS 4
+#define VTK_EXTRACT_CLOSEST_POINT_CLUSTER 5
+
+class vtkDataArray;
+class vtkFloatArray;
+class vtkIdList;
+class vtkIdTypeArray;
+class vtkAbstractPointLocator;
+
+
+class VTKFILTERSPOINTS_EXPORT vtkEuclideanClusterExtraction : public vtkPolyDataAlgorithm
+{
+public:
+  vtkTypeMacro(vtkEuclideanClusterExtraction,vtkPolyDataAlgorithm);
+  void PrintSelf(ostream& os, vtkIndent indent);
+
+  // Description:
+  // Construct with default extraction mode to extract largest clusters.
+  static vtkEuclideanClusterExtraction *New();
+
+  // Description:
+  // Specify the local search radius.
+  vtkSetClampMacro(Radius,double,0.0,VTK_FLOAT_MAX);
+  vtkGetMacro(Radius,double);
+
+  // Description:
+  // Turn on/off connectivity based on scalar value. If on, points are
+  // connected only if the are proximal AND the scalar value of a candiate
+  // point falls in the scalar range specified. Of course input point scalar
+  // data must be provided.
+  vtkSetMacro(ScalarConnectivity,bool);
+  vtkGetMacro(ScalarConnectivity,bool);
+  vtkBooleanMacro(ScalarConnectivity,bool);
+
+  // Description:
+  // Set the scalar range used to extract points based on scalar connectivity.
+  vtkSetVector2Macro(ScalarRange,double);
+  vtkGetVector2Macro(ScalarRange,double);
+
+  // Description:
+  // Control the extraction of connected surfaces.
+  vtkSetClampMacro(ExtractionMode,int,
+            VTK_EXTRACT_POINT_SEEDED_CLUSTERS,VTK_EXTRACT_CLOSEST_POINT_CLUSTER);
+  vtkGetMacro(ExtractionMode,int);
+  void SetExtractionModeToPointSeededClusters()
+    {this->SetExtractionMode(VTK_EXTRACT_POINT_SEEDED_CLUSTERS);};
+  void SetExtractionModeToLargestCluster()
+    {this->SetExtractionMode(VTK_EXTRACT_LARGEST_CLUSTER);};
+  void SetExtractionModeToSpecifiedClusters()
+    {this->SetExtractionMode(VTK_EXTRACT_SPECIFIED_CLUSTERS);};
+  void SetExtractionModeToClosestPointCluster()
+    {this->SetExtractionMode(VTK_EXTRACT_CLOSEST_POINT_CLUSTER);};
+  void SetExtractionModeToAllClusters()
+    {this->SetExtractionMode(VTK_EXTRACT_ALL_CLUSTERS);};
+  const char *GetExtractionModeAsString();
+
+  // Description:
+  // Initialize the list of point ids used to seed clusters.
+  void InitializeSeedList();
+
+  // Description:
+  // Add a seed id (point id). Note: ids are 0-offset.
+  void AddSeed(vtkIdType id);
+
+  // Description:
+  // Delete a seed id.a
+  void DeleteSeed(vtkIdType id);
+
+  // Description:
+  // Initialize the list of cluster ids to extract.
+  void InitializeSpecifiedClusterList();
+
+  // Description:
+  // Add a cluster id to extract. Note: ids are 0-offset.
+  void AddSpecifiedCluster(int id);
+
+  // Description:
+  // Delete a cluster id to extract.
+  void DeleteSpecifiedCluster(int id);
+
+  // Description:
+  // Used to specify the x-y-z point coordinates when extracting the cluster
+  // closest to a specified point.
+  vtkSetVector3Macro(ClosestPoint,double);
+  vtkGetVectorMacro(ClosestPoint,double,3);
+
+  // Description:
+  // Obtain the number of connected clusters. This value is valid only after filter execution.
+  int GetNumberOfExtractedClusters();
+
+  // Description:
+  // Turn on/off the coloring of connected clusters.
+  vtkSetMacro(ColorClusters,bool);
+  vtkGetMacro(ColorClusters,bool);
+  vtkBooleanMacro(ColorClusters,bool);
+
+  // Description:
+  // Specify a point locator. By default a vtkStaticPointLocator is
+  // used. The locator performs efficient proximity searches near a
+  // specified interpolation position.
+  void SetLocator(vtkAbstractPointLocator *locator);
+  vtkGetObjectMacro(Locator,vtkAbstractPointLocator);
+
+protected:
+  vtkEuclideanClusterExtraction();
+  ~vtkEuclideanClusterExtraction();
+
+  double Radius; //connection radius
+  bool ColorClusters; //boolean turns on/off scalar gen for separate clusters
+  int ExtractionMode; //how to extract clusters
+  vtkIdList *Seeds; //id's of points or cells used to seed clusters
+  vtkIdList *SpecifiedClusterIds; //clusters specified for extraction
+  vtkIdTypeArray *ClusterSizes; //size (in cells) of each cluster extracted
+
+  double ClosestPoint[3];
+
+  bool ScalarConnectivity;
+  double ScalarRange[2];
+
+  vtkAbstractPointLocator *Locator;
+
+  // Configure the pipeline
+  virtual int RequestData(vtkInformation *, vtkInformationVector **,
+                          vtkInformationVector *);
+  virtual int FillInputPortInformation(int port, vtkInformation *info);
+
+  // Internal method for propagating connected waves.
+  void InsertIntoWave(vtkIdList *wave, vtkIdType ptId);
+  void TraverseAndMark(vtkPoints *pts);
+
+private:
+  vtkEuclideanClusterExtraction(const vtkEuclideanClusterExtraction&) VTK_DELETE_FUNCTION;
+  void operator=(const vtkEuclideanClusterExtraction&) VTK_DELETE_FUNCTION;
+
+  // used to support algorithm execution
+  vtkFloatArray *NeighborScalars;
+  vtkIdList *NeighborPointIds;
+  char *Visited;
+  vtkIdType *PointMap;
+  vtkIdTypeArray *NewScalars;
+  vtkIdType ClusterNumber;
+  vtkIdType PointNumber;
+  vtkIdType NumPointsInCluster;
+  vtkDataArray *InScalars;
+  vtkIdList *Wave;
+  vtkIdList *Wave2;
+  vtkIdList *PointIds;
+
+};
+
+// Description:
+// Return the method of extraction as a string.
+inline const char *vtkEuclideanClusterExtraction::GetExtractionModeAsString(void)
+{
+  if ( this->ExtractionMode == VTK_EXTRACT_POINT_SEEDED_CLUSTERS )
+    {
+    return "ExtractPointSeededClusters";
+    }
+  else if ( this->ExtractionMode == VTK_EXTRACT_SPECIFIED_CLUSTERS )
+    {
+    return "ExtractSpecifiedClusters";
+    }
+  else if ( this->ExtractionMode == VTK_EXTRACT_ALL_CLUSTERS )
+    {
+    return "ExtractAllClusters";
+    }
+  else if ( this->ExtractionMode == VTK_EXTRACT_CLOSEST_POINT_CLUSTER )
+    {
+    return "ExtractClosestPointCluster";
+    }
+  else
+    {
+    return "ExtractLargestCluster";
+    }
+}
+
+#endif
diff --git a/Filters/Points/vtkExtractHierarchicalBins.cxx b/Filters/Points/vtkExtractHierarchicalBins.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..8344407ab11e04eb9dac31bed7936edc3646263f
--- /dev/null
+++ b/Filters/Points/vtkExtractHierarchicalBins.cxx
@@ -0,0 +1,102 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkExtractHierarchicalBins.cxx
+
+  Copyright (c) Kitware, Inc.
+  All rights reserved.
+  See LICENSE file 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.
+
+=========================================================================*/
+#include "vtkExtractHierarchicalBins.h"
+
+#include "vtkObjectFactory.h"
+#include "vtkPointSet.h"
+#include "vtkPoints.h"
+#include "vtkDataArray.h"
+#include "vtkHierarchicalBinningFilter.h"
+
+vtkStandardNewMacro(vtkExtractHierarchicalBins);
+vtkCxxSetObjectMacro(vtkExtractHierarchicalBins,BinningFilter,vtkHierarchicalBinningFilter);
+
+//----------------------------------------------------------------------------
+// Helper classes to support efficient computing, and threaded execution.
+namespace {
+
+//----------------------------------------------------------------------------
+// Mark points to be extracted
+static void MaskPoints(vtkIdType numPts, vtkIdType *map, vtkIdType offset,
+                       vtkIdType numFill)
+{
+  std::fill_n(map, offset, static_cast<vtkIdType>(-1));
+  std::fill_n(map+offset, numFill, static_cast<vtkIdType>(1));
+  std::fill_n(map+offset+numFill, numPts-(offset+numFill), static_cast<vtkIdType>(-1));
+}
+
+} //anonymous namespace
+
+//================= Begin class proper =======================================
+//----------------------------------------------------------------------------
+vtkExtractHierarchicalBins::vtkExtractHierarchicalBins()
+{
+  this->Level = 0;
+  this->Bin = -1;
+  this->BinningFilter = NULL;
+}
+
+//----------------------------------------------------------------------------
+vtkExtractHierarchicalBins::~vtkExtractHierarchicalBins()
+{
+  this->SetBinningFilter(NULL);
+}
+
+//----------------------------------------------------------------------------
+// Traverse all the input points and extract points that are contained within
+// and implicit function.
+int vtkExtractHierarchicalBins::FilterPoints(vtkPointSet *input)
+{
+  // Check the input.
+  if ( !this->BinningFilter )
+    {
+    vtkErrorMacro(<<"vtkHierarchicalBinningFilter required\n");
+    return 0;
+    }
+
+  // Access the correct bin and determine how many points to extract.
+  vtkIdType offset;
+  vtkIdType numFill;
+
+  if ( this->Level >= 0 )
+    {
+    offset = this->BinningFilter->GetLevelOffset(this->Level, numFill);
+    }
+  else if ( this->Bin >= 0 )
+    {
+    offset = this->BinningFilter->GetBinOffset(this->Bin, numFill);
+    }
+  else //pass everything through
+    {
+    return 1;
+    }
+
+  vtkIdType numPts = input->GetNumberOfPoints();
+  MaskPoints(numPts, this->PointMap, offset, numFill);
+
+  return 1;
+}
+
+//----------------------------------------------------------------------------
+void vtkExtractHierarchicalBins::PrintSelf(ostream& os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os,indent);
+
+  os << indent << "Level: " << this->Level << "\n";
+  os << indent << "Bin: " << this->Bin << "\n";
+  os << indent << "Binning Filter: "
+     << static_cast<void *>(this->BinningFilter) << "\n";
+
+}
diff --git a/Filters/Points/vtkExtractHierarchicalBins.h b/Filters/Points/vtkExtractHierarchicalBins.h
new file mode 100644
index 0000000000000000000000000000000000000000..c73b1493ca6df0b5be846d2dceaf28ae0bfc4ac2
--- /dev/null
+++ b/Filters/Points/vtkExtractHierarchicalBins.h
@@ -0,0 +1,102 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkExtractHierarchicalBins.h
+
+  Copyright (c) Kitware, Inc.
+  All rights reserved.
+  See LICENSE file 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.
+
+=========================================================================*/
+// .NAME vtkExtractHierarchicalBins - manipulate the output of
+// vtkHierarchicalBinningFilter
+
+// .SECTION Description
+// vtkExtractHierarchicalBins enables users to extract data from the output
+// of vtkHierarchicalBinningFilter. Points at a particular level, or at a
+// level and bin number, can be filtered to the output. To perform these
+// operations, the output must contain points sorted into bins (the
+// vtkPoints), with offsets pointing to the beginning of each bin (a
+// vtkFieldData array named "BinOffsets").
+//
+
+// .SECTION Caveats
+// This class has been threaded with vtkSMPTools. Using TBB or other
+// non-sequential type (set in the CMake variable
+// VTK_SMP_IMPLEMENTATION_TYPE) may improve performance significantly.
+
+// .SECTION See Also
+// vtkFiltersPointsFilter vtkRadiusOutlierRemoval vtkStatisticalOutlierRemoval
+// vtkThresholdPoints vtkImplicitFunction vtkExtractGeoemtry
+// vtkFitImplicitFunction
+
+#ifndef vtkExtractHierarchicalBins_h
+#define vtkExtractHierarchicalBins_h
+
+#include "vtkFiltersPointsModule.h" // For export macro
+#include "vtkPointCloudFilter.h"
+
+class vtkHierarchicalBinningFilter;
+class vtkPointSet;
+
+
+class VTKFILTERSPOINTS_EXPORT vtkExtractHierarchicalBins : public vtkPointCloudFilter
+{
+public:
+  // Description:
+  // Standard methods for instantiating, obtaining type information, and
+  // printing information.
+  static vtkExtractHierarchicalBins *New();
+  vtkTypeMacro(vtkExtractHierarchicalBins,vtkPointCloudFilter);
+  void PrintSelf(ostream& os, vtkIndent indent);
+
+  // Description:
+  // Specify the level to extract. If non-negative, with a negative bin
+  // number, then all points at this level are extracted and sent to the
+  // output. If negative, then the points from the specified bin are sent to
+  // the output. If both the level and bin number are negative values, then the
+  // input is sent to the output. By default the 0th level is extracted.
+  vtkSetMacro(Level,int);
+  vtkGetMacro(Level,int);
+
+  // Description:
+  // Specify the bin number to extract. If a non-negative value, then the
+  // points from the bin number specified are extracted. If negative, then
+  // entire levels of points are extacted (assuming the Level is
+  // non-negative). Note that the bin tree is flattened, a particular
+  // bin number may refer to a bin on any level.
+  vtkSetMacro(Bin,int);
+  vtkGetMacro(Bin,int);
+
+  // Description:
+  // Specify the vtkHierarchicalBinningFilter to query for relavant
+  // information. Make sure that this filter has executed prior to the execution of
+  // this filter. (This is generally a safe bet if connected in a pipeline.)
+  virtual void SetBinningFilter(vtkHierarchicalBinningFilter*);
+  vtkGetObjectMacro(BinningFilter,vtkHierarchicalBinningFilter);
+
+
+protected:
+  vtkExtractHierarchicalBins();
+  ~vtkExtractHierarchicalBins();
+
+  // Users can extract points from a particular level or bin.
+  int Level;
+  int Bin;
+  vtkHierarchicalBinningFilter *BinningFilter;
+
+  // All derived classes must implement this method. Note that a side effect of
+  // the class is to populate the PointMap. Zero is returned if there is a failure.
+  virtual int FilterPoints(vtkPointSet *input);
+
+private:
+  vtkExtractHierarchicalBins(const vtkExtractHierarchicalBins&) VTK_DELETE_FUNCTION;
+  void operator=(const vtkExtractHierarchicalBins&) VTK_DELETE_FUNCTION;
+
+};
+
+#endif
diff --git a/Filters/Points/vtkExtractPointCloudPiece.cxx b/Filters/Points/vtkExtractPointCloudPiece.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..e1a4232bc88bedefdb9c1fc0cb6b6d801173bb27
--- /dev/null
+++ b/Filters/Points/vtkExtractPointCloudPiece.cxx
@@ -0,0 +1,137 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkExtractPointCloudPiece.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.
+
+=========================================================================*/
+#include "vtkExtractPointCloudPiece.h"
+
+#include "vtkInformation.h"
+#include "vtkInformationVector.h"
+#include "vtkNew.h"
+#include "vtkObjectFactory.h"
+#include "vtkPointData.h"
+// #include "vtkPolyData.h"
+#include "vtkStreamingDemandDrivenPipeline.h"
+#include "vtkDoubleArray.h"
+
+vtkStandardNewMacro(vtkExtractPointCloudPiece);
+
+//-----------------------------------------------------------------------------
+vtkExtractPointCloudPiece::vtkExtractPointCloudPiece()
+{
+  this->ModuloOrdering = true;
+}
+
+//-----------------------------------------------------------------------------
+int vtkExtractPointCloudPiece::RequestUpdateExtent(
+  vtkInformation *vtkNotUsed(request),
+  vtkInformationVector **inputVector,
+  vtkInformationVector *vtkNotUsed(outputVector))
+{
+  // get the info object
+  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
+
+  inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER(), 0);
+  inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES(), 1);
+  inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS(), 0);
+
+  return 1;
+}
+
+//-----------------------------------------------------------------------------
+int vtkExtractPointCloudPiece::RequestData(
+  vtkInformation *vtkNotUsed(request),
+  vtkInformationVector **inputVector,
+  vtkInformationVector *outputVector)
+{
+  // get the info objects
+  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
+  vtkInformation *outInfo = outputVector->GetInformationObject(0);
+
+  // get the input and output
+  vtkPolyData *input = vtkPolyData::SafeDownCast(
+    inInfo->Get(vtkDataObject::DATA_OBJECT()));
+  vtkPolyData *output = vtkPolyData::SafeDownCast(
+    outInfo->Get(vtkDataObject::DATA_OBJECT()));
+
+  // handle field data
+  vtkFieldData *fd = input->GetFieldData();
+  vtkFieldData *outFD = output->GetFieldData();
+  vtkDataArray *offsets = fd->GetArray("BinOffsets");
+  // we wipe the field data as the early viesion of the binner
+  // was producing some huge field data that was killing file IO times
+  outFD->Initialize();
+
+  // Pipeline update piece will tell us what to generate.
+  int piece = outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER());
+
+  vtkIdType startIndex, endIndex;
+  if (vtkIntArray::SafeDownCast(offsets))
+    {
+    vtkIntArray *ioffs = vtkIntArray::SafeDownCast(offsets);
+    startIndex = ioffs->GetValue(piece);
+    endIndex = ioffs->GetValue(piece+1);
+    }
+  else
+    {
+    vtkIdTypeArray *ioffs = vtkIdTypeArray::SafeDownCast(offsets);
+    startIndex = ioffs->GetValue(piece);
+    endIndex = ioffs->GetValue(piece+1);
+    }
+
+  vtkIdType numPts = endIndex - startIndex;
+  vtkPointData *pd = input->GetPointData();
+  vtkPointData *outPD = output->GetPointData();
+  outPD->CopyAllocate(pd,numPts);
+
+  vtkNew<vtkPoints> newPoints;
+  newPoints->Allocate(numPts);
+
+  newPoints->SetNumberOfPoints(numPts);
+
+  if (this->ModuloOrdering)
+    {
+    // loop over points copying them to the output
+    // we do it in an mod 11 approach to add some randomization to the order
+    vtkIdType inIdx = 0;
+    vtkIdType nextStart = 1;
+    for (vtkIdType i = 0; i < numPts; i++)
+      {
+      newPoints->SetPoint(i,input->GetPoint(inIdx+startIndex));
+      outPD->CopyData(pd, inIdx + startIndex, i);
+      inIdx += 11;
+      if (inIdx >= numPts)
+        {
+        inIdx = nextStart;
+        nextStart++;
+        }
+      }
+    }
+  else // otherwise no reordering
+    {
+    // copy the points
+    newPoints->InsertPoints(0, numPts, startIndex, input->GetPoints());
+    // copy point data
+    outPD->CopyData(pd, 0, numPts, startIndex);
+    }
+
+  output->SetPoints(newPoints.Get());
+
+  return 1;
+}
+
+//-----------------------------------------------------------------------------
+void vtkExtractPointCloudPiece::PrintSelf(ostream& os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os,indent);
+  os << indent << "ModuloOrdering: " << this->ModuloOrdering << "\n";
+}
diff --git a/Filters/Points/vtkExtractPointCloudPiece.h b/Filters/Points/vtkExtractPointCloudPiece.h
new file mode 100644
index 0000000000000000000000000000000000000000..225e2c02bc4674941bb780e037b036dec5abec66
--- /dev/null
+++ b/Filters/Points/vtkExtractPointCloudPiece.h
@@ -0,0 +1,61 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkExtractPointCloudPiece.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.
+
+=========================================================================*/
+// .NAME vtkExtractPointCloudPiece - Return a piece of a point cloud
+// .SECTION Description
+// This filter takes the output of a vtkHierarchicalBinningFilter and allows
+// the pipeline to stream it. Pieces are detemined from an offset integral
+// array is associated with the field data of the input.
+
+#ifndef vtkExtractPointCloudPiece_h
+#define vtkExtractPointCloudPiece_h
+
+#include "vtkFiltersPointsModule.h" // For export macro
+#include "vtkPolyDataAlgorithm.h"
+
+class vtkIdList;
+class vtkIntArray;
+
+class VTKFILTERSPOINTS_EXPORT vtkExtractPointCloudPiece : public vtkPolyDataAlgorithm
+{
+public:
+  // Description:
+  // Standard methods for instantiation, printing, and type information.
+  static vtkExtractPointCloudPiece *New();
+  vtkTypeMacro(vtkExtractPointCloudPiece, vtkPolyDataAlgorithm);
+  void PrintSelf(ostream& os, vtkIndent indent);
+
+  // Description:
+  // Turn on or off modulo sampling of the points. By default this is on and the
+  // points in a given piece will be reordered in an attempt to reduce spatial
+  // coherency.
+  vtkSetMacro(ModuloOrdering,bool);
+  vtkGetMacro(ModuloOrdering,bool);
+  vtkBooleanMacro(ModuloOrdering,bool);
+
+protected:
+  vtkExtractPointCloudPiece();
+  ~vtkExtractPointCloudPiece() {}
+
+  // Usual data generation method
+  int RequestData(vtkInformation *, vtkInformationVector **, vtkInformationVector *);
+  int RequestUpdateExtent(vtkInformation *, vtkInformationVector **, vtkInformationVector *);
+  bool ModuloOrdering;
+
+private:
+  vtkExtractPointCloudPiece(const vtkExtractPointCloudPiece&) VTK_DELETE_FUNCTION;
+  void operator=(const vtkExtractPointCloudPiece&) VTK_DELETE_FUNCTION;
+};
+
+#endif
diff --git a/Filters/Points/vtkExtractPoints.cxx b/Filters/Points/vtkExtractPoints.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..e9f43d372cf9aa14135192fba82a297a628ad398
--- /dev/null
+++ b/Filters/Points/vtkExtractPoints.cxx
@@ -0,0 +1,140 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkExtractPoints.cxx
+
+  Copyright (c) Kitware, Inc.
+  All rights reserved.
+  See LICENSE file 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.
+
+=========================================================================*/
+#include "vtkExtractPoints.h"
+
+#include "vtkObjectFactory.h"
+#include "vtkPointSet.h"
+#include "vtkPoints.h"
+#include "vtkImplicitFunction.h"
+#include "vtkSMPTools.h"
+
+vtkStandardNewMacro(vtkExtractPoints);
+vtkCxxSetObjectMacro(vtkExtractPoints,ImplicitFunction,vtkImplicitFunction);
+
+//----------------------------------------------------------------------------
+// Helper classes to support efficient computing, and threaded execution.
+namespace {
+
+//----------------------------------------------------------------------------
+// The threaded core of the algorithm
+template <typename T>
+struct ExtractPoints
+{
+  const T *Points;
+  vtkImplicitFunction *Function;
+  bool ExtractInside;
+  vtkIdType *PointMap;
+
+  ExtractPoints(T *points, vtkImplicitFunction *f, bool inside, vtkIdType *map) :
+    Points(points), Function(f), ExtractInside(inside), PointMap(map)
+    {
+    }
+
+  void operator() (vtkIdType ptId, vtkIdType endPtId)
+    {
+      const T *p = this->Points + 3*ptId;
+      vtkIdType *map = this->PointMap + ptId;
+      vtkImplicitFunction *f = this->Function;
+      double x[3];
+      double inside = (this->ExtractInside ? 1.0 : -1.0);
+
+      for ( ; ptId < endPtId; ++ptId)
+        {
+        x[0] = static_cast<double>(*p++);
+        x[1] = static_cast<double>(*p++);
+        x[2] = static_cast<double>(*p++);
+
+        *map++ = ((f->FunctionValue(x) * inside) <= 0.0 ? 1 : -1 );
+        }
+    }
+
+  static void Execute(vtkExtractPoints *self, vtkIdType numPts,
+                      T *points, vtkIdType *map)
+    {
+      ExtractPoints extract(points, self->GetImplicitFunction(),
+                            self->GetExtractInside(), map);
+      vtkSMPTools::For(0, numPts, extract);
+    }
+
+}; //ExtractPoints
+
+} //anonymous namespace
+
+//================= Begin class proper =======================================
+//----------------------------------------------------------------------------
+vtkExtractPoints::vtkExtractPoints()
+{
+  this->ImplicitFunction = NULL;
+  this->ExtractInside = true;
+}
+
+//----------------------------------------------------------------------------
+vtkExtractPoints::~vtkExtractPoints()
+{
+  this->SetImplicitFunction(NULL);
+}
+
+//----------------------------------------------------------------------------
+// Overload standard modified time function. If implicit function is modified,
+// then this object is modified as well.
+vtkMTimeType vtkExtractPoints::GetMTime()
+{
+  vtkMTimeType mTime=this->MTime.GetMTime();
+  vtkMTimeType impFuncMTime;
+
+  if ( this->ImplicitFunction != NULL )
+    {
+    impFuncMTime = this->ImplicitFunction->GetMTime();
+    mTime = ( impFuncMTime > mTime ? impFuncMTime : mTime );
+    }
+
+  return mTime;
+}
+
+//----------------------------------------------------------------------------
+// Traverse all the input points and extract points that are contained within
+// and implicit function.
+int vtkExtractPoints::FilterPoints(vtkPointSet *input)
+{
+  // Check the input.
+  if ( !this->ImplicitFunction )
+    {
+    vtkErrorMacro(<<"Implicit function required\n");
+    return 0;
+    }
+
+  // Determine which points, if any, should be removed. We create a map
+  // to keep track. The bulk of the algorithmic work is done in this pass.
+  vtkIdType numPts = input->GetNumberOfPoints();
+  void *inPtr = input->GetPoints()->GetVoidPointer(0);
+  switch (input->GetPoints()->GetDataType())
+    {
+    vtkTemplateMacro(ExtractPoints<VTK_TT>::
+                     Execute(this, numPts, (VTK_TT *)inPtr, this->PointMap));
+    }
+
+  return 1;
+}
+
+//----------------------------------------------------------------------------
+void vtkExtractPoints::PrintSelf(ostream& os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os,indent);
+
+  os << indent << "Implicit Function: "
+     << static_cast<void *>(this->ImplicitFunction) << "\n";
+  os << indent << "Extract Inside: "
+     << (this->ExtractInside ? "On\n" : "Off\n");
+}
diff --git a/Filters/Points/vtkExtractPoints.h b/Filters/Points/vtkExtractPoints.h
new file mode 100644
index 0000000000000000000000000000000000000000..c8e3a65471bd2abd72ce551e3a350953eb0b817c
--- /dev/null
+++ b/Filters/Points/vtkExtractPoints.h
@@ -0,0 +1,101 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkExtractPoints.h
+
+  Copyright (c) Kitware, Inc.
+  All rights reserved.
+  See LICENSE file 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.
+
+=========================================================================*/
+// .NAME vtkExtractPoints - extract points within an implicit function
+
+// .SECTION Description
+// vtkExtractPoints removes points that are either inside or outside of a
+// vtkImplicitFunction. Implicit functions in VTK defined as function of the
+// form f(x,y,z)=c, where values c<=0 are interior values of the implicit
+// function. Typical examples include planes, spheres, cylinders, cones,
+// etc. plus boolean combinations of these functions. (This operation
+// presumes closure on the set, so points on the boundary are also considered
+// to be inside.)
+//
+// Note that while any vtkPointSet type can be provided as input, the output is
+// represented by an explicit representation of points via a
+// vtkPolyData. This output polydata will populate its instance of vtkPoints,
+// but no cells will be defined (i.e., no vtkVertex or vtkPolyVertex are
+// contained in the output). Also, after filter execution, the user can
+// request a vtkIdType* map which indicates how the input points were mapped
+// to the output. A value of map[i] (where i is the ith input point) less
+// than 0 means that the ith input point was removed. (See also the
+// superclass documentation for accessing the removed points through the
+// filter's second output.)
+
+// .SECTION Caveats
+// This class has been threaded with vtkSMPTools. Using TBB or other
+// non-sequential type (set in the CMake variable
+// VTK_SMP_IMPLEMENTATION_TYPE) may improve performance significantly.
+
+// .SECTION See Also
+// vtkPointCloudFilter vtkRadiusOutlierRemoval vtkStatisticalOutlierRemoval
+// vtkThresholdPoints vtkImplicitFunction vtkExtractGeoemtry
+// vtkFitImplicitFunction
+
+#ifndef vtkExtractPoints_h
+#define vtkExtractPoints_h
+
+#include "vtkFiltersPointsModule.h" // For export macro
+#include "vtkPointCloudFilter.h"
+
+class vtkImplicitFunction;
+class vtkPointSet;
+
+
+class VTKFILTERSPOINTS_EXPORT vtkExtractPoints : public vtkPointCloudFilter
+{
+public:
+  // Description:
+  // Standard methods for instantiating, obtaining type information, and
+  // printing information.
+  static vtkExtractPoints *New();
+  vtkTypeMacro(vtkExtractPoints,vtkPointCloudFilter);
+  void PrintSelf(ostream& os, vtkIndent indent);
+
+  // Description:
+  // Specify the implicit function for inside/outside checks.
+  virtual void SetImplicitFunction(vtkImplicitFunction*);
+  vtkGetObjectMacro(ImplicitFunction,vtkImplicitFunction);
+
+  // Description:
+  // Boolean controls whether to extract points that are inside of implicit
+  // function (ExtractInside == true) or outside of implicit function
+  // (ExtractInside == false). By default, ExtractInside is true.
+  vtkSetMacro(ExtractInside,bool);
+  vtkGetMacro(ExtractInside,bool);
+  vtkBooleanMacro(ExtractInside,bool);
+
+  // Description:
+  // Return the MTime taking into account changes to the implicit function
+  virtual vtkMTimeType GetMTime();
+
+protected:
+  vtkExtractPoints();
+  ~vtkExtractPoints();
+
+  vtkImplicitFunction *ImplicitFunction;
+  bool ExtractInside;
+
+  // All derived classes must implement this method. Note that a side effect of
+  // the class is to populate the PointMap. Zero is returned if there is a failure.
+  virtual int FilterPoints(vtkPointSet *input);
+
+private:
+  vtkExtractPoints(const vtkExtractPoints&) VTK_DELETE_FUNCTION;
+  void operator=(const vtkExtractPoints&) VTK_DELETE_FUNCTION;
+
+};
+
+#endif
diff --git a/Filters/Points/vtkExtractSurface.cxx b/Filters/Points/vtkExtractSurface.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..4e32fa398556e1bbd5837ca72dcb0b47fe5da815
--- /dev/null
+++ b/Filters/Points/vtkExtractSurface.cxx
@@ -0,0 +1,1423 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkExtractSurface.cxx
+
+  Copyright (c) Kitware, Inc.
+  All rights reserved.
+  See LICENSE file 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.
+
+=========================================================================*/
+#include "vtkExtractSurface.h"
+
+#include "vtkMath.h"
+#include "vtkImageData.h"
+#include "vtkCellArray.h"
+#include "vtkInformation.h"
+#include "vtkInformationIntegerVectorKey.h"
+#include "vtkInformationVector.h"
+#include "vtkObjectFactory.h"
+#include "vtkPointData.h"
+#include "vtkPolyData.h"
+#include "vtkFloatArray.h"
+#include "vtkStreamingDemandDrivenPipeline.h"
+#include "vtkMarchingCubesTriangleCases.h"
+#include "vtkSMPTools.h"
+
+#include <cmath>
+
+vtkStandardNewMacro(vtkExtractSurface);
+
+
+//----------------------------------------------------------------------------
+
+// This templated class implements the heart of the algorithm.
+// vtkExtractSurface populates the information in this class and
+// then invokes Contour() to actually initiate execution.
+template <class T>
+class vtkExtractSurfaceAlgorithm
+{
+public:
+  // Edge case table values.
+  enum EdgeClass {
+    Below = 0, //below isovalue
+    Above = 1, //above isovalue
+    LeftAbove = 1, //left vertex is above isovalue
+    RightAbove = 2, //right vertex is above isovalue
+    BothAbove = 3, //entire edge is above isovalue
+    Empty = 4 //undefined edges should not be processed
+  };
+
+  // Dealing with boundary situations when processing volumes.
+  enum CellClass {
+    Interior = 0,
+    MinBoundary = 1,
+    MaxBoundary = 2
+  };
+
+  // Edge-based case table to generate output triangle primitives. It is
+  // equivalent to the vertex-based Marching Cubes case table but provides
+  // several computational advantages (parallel separability, more efficient
+  // computation). This table is built from the MC case table when the class
+  // is instantiated.
+  unsigned char EdgeCases[256][16];
+
+  // A table to map old edge ids (as defined from vtkMarchingCubesCases) into
+  // the edge-based case table. This is so that the existing Marching Cubes
+  // case tables can be reused.
+  static const unsigned char EdgeMap[12];
+
+  // A table that lists voxel point ids as a function of edge ids (edge ids
+  // for edge-based case table).
+  static const unsigned char VertMap[12][2];
+
+  // A table describing vertex offsets (in index space) from the cube axes
+  // origin for each of the eight vertices of a voxel.
+  static const unsigned char VertOffsets[8][3];
+
+  // This table is used to accelerate the generation of output triangles and
+  // points. The EdgeUses array, a function of the voxel case number,
+  // indicates which voxel edges intersect with the contour (i.e., require
+  // interpolation). This array is filled in at instantiation during the case
+  // table generation process.
+  unsigned char EdgeUses[256][12];
+
+  // Flags indicate whether a particular case requires voxel axes to be
+  // processed. A cheap acceleration structure computed from the case
+  // tables at the point of instantiation.
+  unsigned char IncludesAxes[256];
+
+  // Algorithm-derived data. XCases tracks the x-row edge cases. The
+  // EdgeMetaData tracks information needed for parallel partitioning,
+  // and to enable generation of the output primitives without using
+  // a point locator.
+  unsigned char *XCases;
+  vtkIdType *EdgeMetaData;
+
+  // Internal variables used by the various algorithm methods. Interfaces VTK
+  // image data in a form more convenient to the algorithm.
+  T        *Scalars;
+  double    Radius;
+  vtkIdType Dims[3];
+  double    Origin[3];
+  double    Spacing[3];
+  vtkIdType NumberOfEdges;
+  vtkIdType SliceOffset;
+  int Min0;
+  int Max0;
+  int Inc0;
+  int Min1;
+  int Max1;
+  int Inc1;
+  int Min2;
+  int Max2;
+  int Inc2;
+
+  // Output data. Threads write to partitioned memory.
+  vtkIdType *NewTris;
+  float     *NewPoints;
+  float     *NewGradients;
+  float     *NewNormals;
+  bool       NeedGradients;
+
+  // Setup algorithm
+  vtkExtractSurfaceAlgorithm();
+
+  // Adjust the origin to the lower-left corner of the volume (if necessary)
+  void AdjustOrigin()
+    {
+    this->Origin[0] = this->Origin[0] + this->Spacing[0]*this->Min0;
+    this->Origin[1] = this->Origin[1] + this->Spacing[1]*this->Min1;
+    this->Origin[2] = this->Origin[2] + this->Spacing[2]*this->Min2;;
+    }
+
+  // The three main passes of the algorithm.
+  void ProcessXEdge(double value, T const * const inPtr, vtkIdType row, vtkIdType slice); //PASS 1
+  void ProcessYZEdges(vtkIdType row, vtkIdType slice); //PASS 2
+  void GenerateOutput(double value, T* inPtr, vtkIdType row, vtkIdType slice);//PASS 3
+
+  // Used to extract the edge case separate from the state of the edge. The state is
+  // one of three values: NEAR, EMPTY, or UNSEEN. The state refers to the relationship
+  // of the edge to the signed distance function.
+  unsigned char EdgeCase(unsigned char eCase)
+    {
+      return (eCase & vtkExtractSurfaceAlgorithm::BothAbove);
+    }
+
+  // Place holder for now in case fancy bit fiddling is needed later.
+  void SetXEdge(unsigned char *ePtr, unsigned char edgeCase)
+    {*ePtr = edgeCase;}
+
+  // Given the four x-edge cases defining this voxel, return the voxel case
+  // number.
+  unsigned char GetEdgeCase(unsigned char *ePtr[4])
+    {
+      return ( this->EdgeCase(*(ePtr[0])) | (this->EdgeCase(*(ePtr[1]))<<2) |
+               (this->EdgeCase(*(ePtr[2]))<<4) | (this->EdgeCase(*(ePtr[3]))<<6) );
+    }
+
+  // Given the four x-edge cases defining this voxel, indicate whether the voxel is
+  // valid and primitives are to be generated. This method needs to refer to the
+  // state of the edge.
+  bool GeneratePrimitives(unsigned char *ePtr[4])
+    {
+    if ( *ePtr[0] >= vtkExtractSurfaceAlgorithm::Empty ||
+         *ePtr[1] >= vtkExtractSurfaceAlgorithm::Empty ||
+         *ePtr[2] >= vtkExtractSurfaceAlgorithm::Empty ||
+         *ePtr[3] >= vtkExtractSurfaceAlgorithm::Empty )
+      {
+      return false;
+      }
+    else
+      {
+      return true;
+      }
+    }
+
+  // Return the number of contouring primitives for a particular edge case number.
+  unsigned char GetNumberOfPrimitives(unsigned char eCase)
+    { return this->EdgeCases[eCase][0]; }
+
+  // Return an array indicating which voxel edges intersect the contour.
+  unsigned char *GetEdgeUses(unsigned char eCase)
+    { return this->EdgeUses[eCase]; }
+
+  // Indicate whether voxel axes need processing for this case.
+  unsigned char CaseIncludesAxes(unsigned char eCase)
+    { return this->IncludesAxes[eCase]; }
+
+  // Count edge intersections near volume boundaries.
+  void CountBoundaryYZInts(unsigned char loc, unsigned char *edgeCases,
+                           vtkIdType *eMD[4]);
+
+  // Produce the output triangles for this voxel cell.
+  void GenerateTris(unsigned char eCase, unsigned char numTris, vtkIdType *eIds,
+                    vtkIdType &triId)
+    {
+      vtkIdType *tri;
+      const unsigned char *edges = this->EdgeCases[eCase] + 1;
+      for (int i=0; i < numTris; ++i, edges+=3)
+        {
+        tri = this->NewTris + 4*triId++;
+        tri[0] = 3;
+        tri[1] = eIds[edges[0]];
+        tri[2] = eIds[edges[1]];
+        tri[3] = eIds[edges[2]];
+        }
+    }
+
+  // Compute gradient on interior point.
+  void ComputeGradient(unsigned char loc, vtkIdType ijk[3],
+                       T const * const s0_start, T const * const s0_end,
+                       T const * const s1_start, T const * const s1_end,
+                       T const * const s2_start, T const * const s2_end,
+                       float g[3])
+    {
+      if ( loc == Interior )
+        {
+        g[0] = 0.5*( (*s0_start - *s0_end) / this->Spacing[0] );
+        g[1] = 0.5*( (*s1_start - *s1_end) / this->Spacing[1] );
+        g[2] = 0.5*( (*s2_start - *s2_end) / this->Spacing[2] );
+        }
+      else
+        {
+        this->ComputeBoundaryGradient(ijk,
+                                      s0_start, s0_end,
+                                      s1_start, s1_end,
+                                      s2_start, s2_end,
+                                      g);
+        }
+    }
+
+
+  // Interpolate along a voxel axes edge.
+  void InterpolateAxesEdge(double t, unsigned char loc,
+                           float x0[3],
+                           T const * const s,
+                           const int incs[3],
+                           float x1[3],
+                           vtkIdType vId,
+                           vtkIdType ijk[3],
+                           float g0[3])
+    {
+
+      float *x = this->NewPoints + 3*vId;
+      x[0] = x0[0] + t*(x1[0]-x0[0]);
+      x[1] = x0[1] + t*(x1[1]-x0[1]);
+      x[2] = x0[2] + t*(x1[2]-x0[2]);
+
+      if ( this->NeedGradients )
+        {
+        float gTmp[3], g1[3];
+        this->ComputeGradient(loc,ijk,
+                              s + incs[0], s - incs[0],
+                              s + incs[1], s - incs[1],
+                              s + incs[2], s - incs[2],
+                              g1);
+
+        float *g = ( this->NewGradients ? this->NewGradients + 3*vId : gTmp );
+        g[0] = g0[0] + t*(g1[0]-g0[0]);
+        g[1] = g0[1] + t*(g1[1]-g0[1]);
+        g[2] = g0[2] + t*(g1[2]-g0[2]);
+
+        if ( this->NewNormals )
+          {
+          float *n = this->NewNormals + 3*vId;
+          n[0] = -g[0];
+          n[1] = -g[1];
+          n[2] = -g[2];
+          vtkMath::Normalize(n);
+          }
+        }//if normals or gradients required
+    }
+
+  // Compute the gradient on a point which may be on the boundary of the volume.
+  void ComputeBoundaryGradient(vtkIdType ijk[3],
+                               T const * const s0_start, T const * const s0_end,
+                               T const * const s1_start, T const * const s1_end,
+                               T const * const s2_start, T const * const s2_end,
+                               float g[3]);
+
+  // Interpolate along an arbitrary edge, typically one that may be on the
+  // volume boundary. This means careful computation of stuff requiring
+  // neighborhood information (e.g., gradients).
+  void InterpolateEdge(double value, vtkIdType ijk[3],
+                       T const * const s, const int incs[3],
+                       float x[3],
+                       unsigned char edgeNum,
+                       unsigned char const* const edgeUses,
+                       vtkIdType *eIds);
+
+  // Produce the output points on the voxel axes for this voxel cell.
+  void GeneratePoints(double value, unsigned char loc, vtkIdType ijk[3],
+                      T const * const sPtr, const int incs[3],
+                      float x[3], unsigned char const * const edgeUses,
+                      vtkIdType *eIds);
+
+  // Helper function to set up the point ids on voxel edges.
+  unsigned char InitVoxelIds(unsigned char *ePtr[4], vtkIdType *eMD[4],
+                             vtkIdType *eIds)
+    {
+      unsigned char eCase = this->GetEdgeCase(ePtr);
+      eIds[0] = eMD[0][0]; //x-edges
+      eIds[1] = eMD[1][0];
+      eIds[2] = eMD[2][0];
+      eIds[3] = eMD[3][0];
+      eIds[4] = eMD[0][1]; //y-edges
+      eIds[5] = eIds[4] + this->EdgeUses[eCase][4];
+      eIds[6] = eMD[2][1];
+      eIds[7] = eIds[6] + this->EdgeUses[eCase][6];
+      eIds[8] = eMD[0][2]; //z-edges
+      eIds[9] = eIds[8] + this->EdgeUses[eCase][8];
+      eIds[10] = eMD[1][2];
+      eIds[11] = eIds[10] + this->EdgeUses[eCase][10];
+      return eCase;
+    }
+
+  // Helper function to advance the point ids along voxel rows.
+  void AdvanceVoxelIds(unsigned char eCase, vtkIdType *eIds)
+    {
+      eIds[0] += this->EdgeUses[eCase][0]; //x-edges
+      eIds[1] += this->EdgeUses[eCase][1];
+      eIds[2] += this->EdgeUses[eCase][2];
+      eIds[3] += this->EdgeUses[eCase][3];
+      eIds[4] += this->EdgeUses[eCase][4]; //y-edges
+      eIds[5] = eIds[4] + this->EdgeUses[eCase][5];
+      eIds[6] += this->EdgeUses[eCase][6];
+      eIds[7] = eIds[6] + this->EdgeUses[eCase][7];
+      eIds[8] += this->EdgeUses[eCase][8]; //z-edges
+      eIds[9] = eIds[8] + this->EdgeUses[eCase][9];
+      eIds[10] += this->EdgeUses[eCase][10];
+      eIds[11] = eIds[10] + this->EdgeUses[eCase][11];
+    }
+
+  // Threading integration via SMPTools
+  template <class TT> class Pass1
+    {
+    public:
+      vtkExtractSurfaceAlgorithm<TT> *Algo;
+      double Value;
+      Pass1(vtkExtractSurfaceAlgorithm<TT> *algo, double value)
+        {this->Algo = algo; this->Value = value;}
+      void  operator()(vtkIdType slice, vtkIdType end)
+        {
+        vtkIdType row;
+        TT *rowPtr, *slicePtr = this->Algo->Scalars + slice*this->Algo->Inc2;
+        for ( ; slice < end; ++slice )
+          {
+          for (row=0, rowPtr=slicePtr; row < this->Algo->Dims[1]; ++row)
+            {
+            this->Algo->ProcessXEdge(this->Value, rowPtr, row, slice);
+            rowPtr += this->Algo->Inc1;
+            }//for all rows in this slice
+          slicePtr += this->Algo->Inc2;
+          }//for all slices in this batch
+        }
+    };
+  template <class TT> class Pass2
+    {
+    public:
+      Pass2(vtkExtractSurfaceAlgorithm<TT> *algo)
+        {this->Algo = algo;}
+      vtkExtractSurfaceAlgorithm<TT> *Algo;
+      void  operator()(vtkIdType slice, vtkIdType end)
+        {
+        for ( ; slice < end; ++slice)
+          {
+          for ( vtkIdType row=0; row < (this->Algo->Dims[1]-1); ++row)
+            {
+            this->Algo->ProcessYZEdges(row, slice);
+            }//for all rows in this slice
+          }//for all slices in this batch
+        }
+    };
+  template <class TT> class Pass4
+    {
+    public:
+      Pass4(vtkExtractSurfaceAlgorithm<TT> *algo, double value)
+        {this->Algo = algo; this->Value = value;}
+      vtkExtractSurfaceAlgorithm<TT> *Algo;
+      double Value;
+      void  operator()(vtkIdType slice, vtkIdType end)
+        {
+        vtkIdType row;
+        vtkIdType *eMD0 = this->Algo->EdgeMetaData + slice*6*this->Algo->Dims[1];
+        vtkIdType *eMD1 = eMD0 + 6*this->Algo->Dims[1];
+        TT *rowPtr, *slicePtr = this->Algo->Scalars + slice*this->Algo->Inc2;
+        for ( ; slice < end; ++slice )
+          {
+          // It's possible to skip entire slices if there is nothing to generate
+          if ( eMD1[3] > eMD0[3] ) //there are triangle primitives!
+            {
+            for (row=0, rowPtr=slicePtr; row < this->Algo->Dims[1]-1; ++row)
+              {
+              this->Algo->GenerateOutput(this->Value, rowPtr, row, slice);
+              rowPtr += this->Algo->Inc1;
+              }//for all rows in this slice
+            }//if there are triangles
+          slicePtr += this->Algo->Inc2;
+          eMD0 = eMD1;
+          eMD1 = eMD0 + 6*this->Algo->Dims[1];
+          }//for all slices in this batch
+        }
+    };
+
+  // Interface between VTK and templated functions
+  static void Contour(vtkExtractSurface *self, vtkImageData *input,
+                      int extent[6], vtkIdType *incs, T *scalars,
+                      vtkPoints *newPts, vtkCellArray *newTris,
+                      vtkFloatArray *newNormals, vtkFloatArray *newGradients);
+};
+
+//----------------------------------------------------------------------------
+// Map MC edges numbering to use the saner FlyingEdges edge numbering scheme.
+template <class T> const unsigned char vtkExtractSurfaceAlgorithm<T>::
+EdgeMap[12] = {0,5,1,4,2,7,3,6,8,9,10,11};
+
+//----------------------------------------------------------------------------
+// Map MC edges numbering to use the saner FlyingEdges edge numbering scheme.
+template <class T> const unsigned char vtkExtractSurfaceAlgorithm<T>::
+VertMap[12][2] = {{0,1}, {2,3}, {4,5}, {6,7}, {0,2}, {1,3}, {4,6}, {5,7},
+                  {0,4}, {1,5}, {2,6}, {3,7}};
+
+//----------------------------------------------------------------------------
+// The offsets of each vertex (in index space) from the voxel axes origin.
+template <class T> const unsigned char vtkExtractSurfaceAlgorithm<T>::
+VertOffsets[8][3] = {{0,0,0}, {1,0,0}, {0,1,0}, {1,1,0},
+                     {0,0,1}, {1,0,1}, {0,1,1}, {1,1,1}};
+
+//----------------------------------------------------------------------------
+// Instantiate and initialize key data members. Mostly we build the
+// edge-based case table, and associated acceleration structures, from the
+// marching cubes case table. Some of this code is borrowed shamelessly from
+// vtkVoxel::Contour() method.
+template <class T> vtkExtractSurfaceAlgorithm<T>::
+vtkExtractSurfaceAlgorithm():XCases(NULL),EdgeMetaData(NULL),NewTris(NULL),
+                             NewPoints(NULL),NewGradients(NULL),NewNormals(NULL)
+{
+  int i, j, k, l, ii, eCase, index, numTris;
+  static int vertMap[8] = {0,1,3,2,4,5,7,6};
+  static int CASE_MASK[8] = {1,2,4,8,16,32,64,128};
+  EDGE_LIST *edge;
+  vtkMarchingCubesTriangleCases *triCase;
+  unsigned char *edgeCase;
+
+  // Initialize cases, increments, and edge intersection flags
+  for (eCase=0; eCase<256; ++eCase)
+    {
+    for (j=0; j<16; ++j)
+      {
+      this->EdgeCases[eCase][j] = 0;
+      }
+    for (j=0; j<12; ++j)
+      {
+      this->EdgeUses[eCase][j] = 0;
+      }
+    this->IncludesAxes[eCase] = 0;
+    }
+
+  // The voxel, edge-based case table is a function of the four x-edge cases
+  // that define the voxel. Here we convert the existing MC vertex-based case
+  // table into a x-edge case table. Note that the four x-edges are ordered
+  // (0->3): x, x+y, x+z, x+y+z; the four y-edges are ordered (4->7): y, y+x,
+  // y+z, y+x+z; and the four z-edges are ordered (8->11): z, z+x, z+y,
+  // z+x+y.
+  for (l=0; l<4; ++l)
+    {
+    for (k=0; k<4; ++k)
+      {
+      for (j=0; j<4; ++j)
+        {
+        for (i=0; i<4; ++i)
+          {
+          //yes we could just count to (0->255) but where's the fun in that?
+          eCase = i | (j<<2) | (k<<4) | (l<<6);
+          for ( ii=0, index = 0; ii < 8; ++ii)
+            {
+            if ( eCase & (1<<vertMap[ii]) ) //map into ancient MC table
+              {
+              index |= CASE_MASK[ii];
+              }
+            }
+          //Now build case table
+          triCase = vtkMarchingCubesTriangleCases::GetCases() + index;
+          edge = triCase->edges;
+          for ( numTris=0, edge=triCase->edges; edge[0] > -1; edge += 3 )
+            {//count the number of triangles
+            numTris++;
+            }
+          if ( numTris > 0 )
+            {
+            edgeCase = this->EdgeCases[eCase];
+            *edgeCase++ = numTris;
+            for ( edge = triCase->edges; edge[0] > -1; edge += 3, edgeCase+=3 )
+              {
+              // Build new case table.
+              edgeCase[0] = this->EdgeMap[edge[0]];
+              edgeCase[1] = this->EdgeMap[edge[1]];
+              edgeCase[2] = this->EdgeMap[edge[2]];
+              }
+            }
+          }//x-edges
+        }//x+y-edges
+      }//x+z-edges
+    }//x+y+z-edges
+
+  // Okay now build the acceleration structure. This is used to generate
+  // output points and triangles when processing a voxel x-row as well as to
+  // perform other topological reasoning. This structure is a function of the
+  // particular case number.
+  for (eCase=0; eCase < 256; ++eCase)
+    {
+    edgeCase = this->EdgeCases[eCase];
+    numTris = *edgeCase++;
+
+    // Mark edges that are used by this case.
+    for (i=0; i < numTris*3; ++i) //just loop over all edges
+      {
+      this->EdgeUses[eCase][edgeCase[i]] = 1;
+      }
+
+    this->IncludesAxes[eCase] = this->EdgeUses[eCase][0] |
+      this->EdgeUses[eCase][4] | this->EdgeUses[eCase][8];
+
+    }//for all cases
+}
+
+//----------------------------------------------------------------------------
+// Count intersections along voxel axes. When traversing the volume across
+// x-edges, the voxel axes on the boundary may be undefined near boundaries
+// (because there are no fully-formed cells). Thus the voxel axes on the
+// boundary are treated specially.
+template <class T> void vtkExtractSurfaceAlgorithm<T>::
+CountBoundaryYZInts(unsigned char loc, unsigned char *edgeUses,
+                    vtkIdType *eMD[4])
+{
+  switch (loc)
+    {
+    case 2: //+x boundary
+      eMD[0][1] += edgeUses[5];
+      eMD[0][2] += edgeUses[9];
+      break;
+    case 8: //+y
+      eMD[1][2] += edgeUses[10];
+      break;
+    case 10://+x +y
+      eMD[0][1] += edgeUses[5];
+      eMD[0][2] += edgeUses[9];
+      eMD[1][2] += edgeUses[10];
+      eMD[1][2] += edgeUses[11];
+      break;
+    case 32://+z
+      eMD[2][1] += edgeUses[6];
+      break;
+    case 34: //+x +z
+      eMD[0][1] += edgeUses[5];
+      eMD[0][2] += edgeUses[9];
+      eMD[2][1] += edgeUses[6];
+      eMD[2][1] += edgeUses[7];
+      break;
+    case 40: //+y +z
+      eMD[2][1] += edgeUses[6];
+      eMD[1][2] += edgeUses[10];
+      break;
+    case 42: //+x +y +z happens no more than once per volume
+      eMD[0][1] += edgeUses[5];
+      eMD[0][2] += edgeUses[9];
+      eMD[1][2] += edgeUses[10];
+      eMD[1][2] += edgeUses[11];
+      eMD[2][1] += edgeUses[6];
+      eMD[2][1] += edgeUses[7];
+      break;
+    default: //uh-oh shouldn't happen
+      break;
+    }
+}
+
+//----------------------------------------------------------------------------
+// Compute the gradient when the point may be near the boundary of the
+// volume.
+template <class T> void vtkExtractSurfaceAlgorithm<T>::
+ComputeBoundaryGradient(vtkIdType ijk[3],
+                        T const * const s0_start, T const * const s0_end,
+                        T const * const s1_start, T const * const s1_end,
+                        T const * const s2_start, T const * const s2_end,
+                        float g[3])
+{
+  const T* s = s0_start - this->Inc0;
+
+  if ( ijk[0] == 0 )
+    {
+    g[0] = (*s0_start - *s) / this->Spacing[0];
+    }
+  else if ( ijk[0] >= (this->Dims[0]-1) )
+    {
+    g[0] = (*s - *s0_end) / this->Spacing[0];
+    }
+  else
+    {
+    g[0] = 0.5 * ( (*s0_start - *s0_end) / this->Spacing[0] );
+    }
+
+  if ( ijk[1] == 0 )
+    {
+    g[1] = (*s1_start - *s) / this->Spacing[1];
+    }
+  else if ( ijk[1] >= (this->Dims[1]-1) )
+    {
+    g[1] = (*s - *s1_end) / this->Spacing[1];
+    }
+  else
+    {
+    g[1] = 0.5 * ( (*s1_start - *s1_end) / this->Spacing[1] );
+    }
+
+  if ( ijk[2] == 0 )
+    {
+    g[2] = (*s2_start - *s) / this->Spacing[2];
+    }
+  else if ( ijk[2] >= (this->Dims[2]-1) )
+    {
+    g[2] = (*s - *s2_end) / this->Spacing[2];
+    }
+  else
+    {
+    g[2] = 0.5 * ( (*s2_start - *s2_end) / this->Spacing[2] );
+    }
+}
+
+//----------------------------------------------------------------------------
+// Interpolate a new point along a boundary edge. Make sure to consider
+// proximity to the boundary when computing gradients, etc.
+template <class T> void vtkExtractSurfaceAlgorithm<T>::
+InterpolateEdge(double value, vtkIdType ijk[3],
+                T const * const s,
+                const int incs[3],
+                float x[3],
+                unsigned char edgeNum,
+                unsigned char const * const edgeUses,
+                vtkIdType *eIds)
+{
+  // if this edge is not used then get out
+  if ( ! edgeUses[edgeNum] )
+    {
+    return;
+    }
+
+  // build the edge information
+  const unsigned char *vertMap = this->VertMap[edgeNum];
+
+  float x0[3], x1[3];
+  vtkIdType ijk0[3], ijk1[3], vId=eIds[edgeNum];
+  int i;
+
+  const unsigned char *offsets = this->VertOffsets[vertMap[0]];
+  T const * const s0 = s + offsets[0]*incs[0] +
+                           offsets[1]*incs[1] +
+                           offsets[2]*incs[2];
+  for (i=0; i<3; ++i)
+    {
+    ijk0[i] = ijk[i] + offsets[i];
+    x0[i] = x[i] + offsets[i]*this->Spacing[i];
+    }
+
+  offsets = this->VertOffsets[vertMap[1]];
+  T const * const s1 = s + offsets[0]*incs[0] +
+                           offsets[1]*incs[1] +
+                           offsets[2]*incs[2];
+  for (i=0; i<3; ++i)
+    {
+    ijk1[i] = ijk[i] + offsets[i];
+    x1[i] = x[i] + offsets[i]*this->Spacing[i];
+    }
+
+  // Okay interpolate
+  double t = (value - *s0) / (*s1 - *s0);
+  float *xPtr = this->NewPoints + 3*vId;
+  xPtr[0] = x0[0] + t*(x1[0]-x0[0]);
+  xPtr[1] = x0[1] + t*(x1[1]-x0[1]);
+  xPtr[2] = x0[2] + t*(x1[2]-x0[2]);
+
+  if ( this->NeedGradients )
+    {
+    float gTmp[3], g0[3], g1[3];
+    this->ComputeBoundaryGradient(ijk0,
+                                  s0+incs[0], s0-incs[0],
+                                  s0+incs[1], s0-incs[1],
+                                  s0+incs[2], s0-incs[2],
+                                  g0);
+    this->ComputeBoundaryGradient(ijk1,
+                                  s1+incs[0], s1-incs[0],
+                                  s1+incs[1], s1-incs[1],
+                                  s1+incs[2], s1-incs[2],
+                                  g1);
+
+    float *g = ( this->NewGradients ? this->NewGradients + 3*vId : gTmp );
+    g[0] = g0[0] + t*(g1[0]-g0[0]);
+    g[1] = g0[1] + t*(g1[1]-g0[1]);
+    g[2] = g0[2] + t*(g1[2]-g0[2]);
+
+    if ( this->NewNormals )
+      {
+      float *n = this->NewNormals + 3*vId;
+      n[0] = -g[0];
+      n[1] = -g[1];
+      n[2] = -g[2];
+      vtkMath::Normalize(n);
+      }
+    }//if normals or gradients required
+}
+
+//----------------------------------------------------------------------------
+// Generate the output points and optionally normals, gradients and
+// interpolate attributes.
+template <class T> void vtkExtractSurfaceAlgorithm<T>::
+GeneratePoints(double value, unsigned char loc, vtkIdType ijk[3],
+               T const * const sPtr, const int incs[3],
+               float x[3],
+               unsigned char const * const edgeUses,
+               vtkIdType *eIds)
+{
+  // Create a slightly faster path for voxel axes interior to the volume.
+  float g0[3];
+  if ( this->NeedGradients )
+    {
+    this->ComputeGradient(loc,ijk,
+                          sPtr + incs[0], sPtr - incs[0],
+                          sPtr + incs[1], sPtr - incs[1],
+                          sPtr + incs[2], sPtr - incs[2],
+                          g0);
+    }
+
+  // Interpolate the cell axes edges
+  for(int i=0; i < 3; ++i)
+    {
+    if(edgeUses[i*4])
+      {
+      //edgesUses[0] == x axes edge
+      //edgesUses[4] == y axes edge
+      //edgesUses[8] == z axes edge
+      float x1[3] = {x[0], x[1], x[2] }; x1[i] += this->Spacing[i];
+      vtkIdType ijk1[3] = { ijk[0], ijk[1], ijk[2] }; ++ijk1[i];
+
+      T const * const sPtr2 = (sPtr+incs[i]);
+      double t = (value - *sPtr) / (*sPtr2 - *sPtr);
+      this->InterpolateAxesEdge(t, loc, x, sPtr2, incs, x1, eIds[i*4], ijk1, g0);
+      }
+    }
+
+  // On the boundary cells special work has to be done to cover the partial
+  // cell axes. These are boundary situations where the voxel axes is not
+  // fully formed. These situations occur on the +x,+y,+z volume
+  // boundaries. (The other cases fall through the default: case which is
+  // expected.)
+  //
+  // Note that loc is one of 27 regions in the volume, with (0,1,2)
+  // indicating (interior, min, max) along coordinate axes.
+  switch (loc)
+    {
+    case 2: case 6: case 18: case 22: //+x
+      this->InterpolateEdge(value, ijk, sPtr, incs, x, 5, edgeUses, eIds);
+      this->InterpolateEdge(value, ijk, sPtr, incs, x, 9, edgeUses, eIds);
+      break;
+    case 8: case 9: case 24: case 25: //+y
+      this->InterpolateEdge(value, ijk, sPtr, incs, x, 1, edgeUses, eIds);
+      this->InterpolateEdge(value, ijk, sPtr, incs, x, 10, edgeUses, eIds);
+      break;
+    case 32: case 33: case 36: case 37: //+z
+      this->InterpolateEdge(value, ijk, sPtr, incs, x, 2, edgeUses, eIds);
+      this->InterpolateEdge(value, ijk, sPtr, incs, x, 6, edgeUses, eIds);
+      break;
+    case 10: case 26: //+x +y
+      this->InterpolateEdge(value, ijk, sPtr, incs, x, 1, edgeUses, eIds);
+      this->InterpolateEdge(value, ijk, sPtr, incs, x, 5, edgeUses, eIds);
+      this->InterpolateEdge(value, ijk, sPtr, incs, x, 9, edgeUses, eIds);
+      this->InterpolateEdge(value, ijk, sPtr, incs, x, 10, edgeUses, eIds);
+      this->InterpolateEdge(value, ijk, sPtr, incs, x, 11, edgeUses, eIds);
+      break;
+    case 34: case 38: //+x +z
+      this->InterpolateEdge(value, ijk, sPtr, incs, x, 2, edgeUses, eIds);
+      this->InterpolateEdge(value, ijk, sPtr, incs, x, 5, edgeUses, eIds);
+      this->InterpolateEdge(value, ijk, sPtr, incs, x, 9, edgeUses, eIds);
+      this->InterpolateEdge(value, ijk, sPtr, incs, x, 6, edgeUses, eIds);
+      this->InterpolateEdge(value, ijk, sPtr, incs, x, 7, edgeUses, eIds);
+      break;
+    case 40: case 41: //+y +z
+      this->InterpolateEdge(value, ijk, sPtr, incs, x, 1, edgeUses, eIds);
+      this->InterpolateEdge(value, ijk, sPtr, incs, x, 2, edgeUses, eIds);
+      this->InterpolateEdge(value, ijk, sPtr, incs, x, 3, edgeUses, eIds);
+      this->InterpolateEdge(value, ijk, sPtr, incs, x, 6, edgeUses, eIds);
+      this->InterpolateEdge(value, ijk, sPtr, incs, x, 10, edgeUses, eIds);
+      break;
+    case 42: //+x +y +z happens no more than once per volume
+      this->InterpolateEdge(value, ijk, sPtr, incs, x, 1, edgeUses, eIds);
+      this->InterpolateEdge(value, ijk, sPtr, incs, x, 2, edgeUses, eIds);
+      this->InterpolateEdge(value, ijk, sPtr, incs, x, 3, edgeUses, eIds);
+      this->InterpolateEdge(value, ijk, sPtr, incs, x, 5, edgeUses, eIds);
+      this->InterpolateEdge(value, ijk, sPtr, incs, x, 9, edgeUses, eIds);
+      this->InterpolateEdge(value, ijk, sPtr, incs, x, 10, edgeUses, eIds);
+      this->InterpolateEdge(value, ijk, sPtr, incs, x, 11, edgeUses, eIds);
+      this->InterpolateEdge(value, ijk, sPtr, incs, x, 6, edgeUses, eIds);
+      this->InterpolateEdge(value, ijk, sPtr, incs, x, 7, edgeUses, eIds);
+      break;
+    default: //interior, or -x,-y,-z boundaries
+      return;
+    }
+}
+
+//----------------------------------------------------------------------------
+// PASS 1: Process a single volume x-row (and all of the voxel edges that
+// compose the row). Determine the x-edges case classification, count the
+// number of x-edge intersections, and figure out where intersections along
+// the x-row begins and ends (i.e., gather information for computational
+// trimming).
+template <class T> void vtkExtractSurfaceAlgorithm<T>::
+ProcessXEdge(double value, T const* const inPtr, vtkIdType row, vtkIdType slice)
+{
+  vtkIdType nxcells=this->Dims[0]-1;
+  vtkIdType minInt=nxcells, maxInt = 0;
+  vtkIdType *edgeMetaData;
+  unsigned char *ePtr = this->XCases + slice*this->SliceOffset + row*nxcells;
+  double s0, s1 = static_cast<double>(*inPtr);
+  double radius=this->Radius;
+
+  //run along the entire x-edge computing edge cases
+  edgeMetaData = this->EdgeMetaData + (slice*this->Dims[1] + row)*6;
+  std::fill_n(edgeMetaData, 6, 0);
+
+  vtkIdType sum = 0;
+
+  //pull this out help reduce false sharing
+  vtkIdType inc0 = this->Inc0;
+
+  for (vtkIdType i=0; i < nxcells; ++i, ++ePtr)
+    {
+    s0 = s1;
+    s1 = static_cast<double>(*(inPtr + (i+1)*inc0));
+
+    unsigned char edgeCase = vtkExtractSurfaceAlgorithm::Below;
+    if (s0 >= value)
+      {
+      edgeCase = vtkExtractSurfaceAlgorithm::LeftAbove;
+      }
+    if( s1 >= value)
+      {
+      edgeCase |= vtkExtractSurfaceAlgorithm::RightAbove;
+      }
+
+    // if edge intersects contour
+    if ( edgeCase == vtkExtractSurfaceAlgorithm::LeftAbove ||
+         edgeCase == vtkExtractSurfaceAlgorithm::RightAbove )
+      {
+      ++sum; //increment number of intersections along x-edge
+      minInt = ( i < minInt ? i : minInt);
+      maxInt = i + 1;
+      }//if contour interacts with this x-edge
+
+    if ( s0 >= radius || s1 >= radius )
+      {
+      edgeCase |= vtkExtractSurfaceAlgorithm::Empty;
+      }
+    this->SetXEdge(ePtr, edgeCase);
+    }//for all x-cell edges along this x-edge
+
+  edgeMetaData[0] += sum; //write back the number of intersections along x-edge
+
+  // The beginning and ending of intersections along the edge is used for
+  // computational trimming.
+  edgeMetaData[4] = minInt; //where intersections start along x edge
+  edgeMetaData[5] = maxInt; //where intersections end along x edge
+}
+
+//----------------------------------------------------------------------------
+// PASS 2: Process a single x-row of voxels. Count the number of y- and
+// z-intersections by topological reasoning from x-edge cases. Determine the
+// number of primitives (i.e., triangles) generated from this row. Use
+// computational trimming to reduce work. Note *ePtr[4] is four pointers to
+// four x-edge rows that bound the voxel x-row and which contain edge case
+// information.
+template <class T> void vtkExtractSurfaceAlgorithm<T>::
+ProcessYZEdges(vtkIdType row, vtkIdType slice)
+{
+  // Grab the four edge cases bounding this voxel x-row.
+  unsigned char *ePtr[4], ec0, ec1, ec2, ec3, xInts=1;
+  ePtr[0] = this->XCases + slice*this->SliceOffset + row*(this->Dims[0]-1);
+  ePtr[1] = ePtr[0] + this->Dims[0]-1;
+  ePtr[2] = ePtr[0] + this->SliceOffset;
+  ePtr[3] = ePtr[2] + this->Dims[0]-1;
+
+  // Grab the edge meta data surrounding the voxel row.
+  vtkIdType *eMD[4];
+  eMD[0] = this->EdgeMetaData + (slice*this->Dims[1] + row)*6; //this x-edge
+  eMD[1] = eMD[0] + 6; //x-edge in +y direction
+  eMD[2] = eMD[0] + this->Dims[1]*6; //x-edge in +z direction
+  eMD[3] = eMD[2] + 6; //x-edge in +y+z direction
+
+  // Determine whether this row of x-cells needs processing. If there are no
+  // x-edge intersections, and the state of the four bounding x-edges is the
+  // same, then there is no need for processing.
+  if ( (eMD[0][0] | eMD[1][0] | eMD[2][0] | eMD[3][0]) == 0 ) //any x-ints?
+    {
+    unsigned char eCase0 = this->EdgeCase(*ePtr[0]);
+    unsigned char eCase1 = this->EdgeCase(*ePtr[1]);
+    unsigned char eCase2 = this->EdgeCase(*ePtr[2]);
+    unsigned char eCase3 = this->EdgeCase(*ePtr[3]);
+    if ( eCase0 == eCase1 &&  eCase1 == eCase2 && eCase2 == eCase3 )
+      {
+      return; //there are no y- or z-ints, thus no contour, skip voxel row
+      }
+    else
+      {
+      xInts = 0; //there are y- or z- edge ints however
+      }
+    }
+
+  // Determine proximity to the boundary of volume. This information is used
+  // to count edge intersections in boundary situations.
+  unsigned char loc, yLoc, zLoc, yzLoc;
+  yLoc = (row >= (this->Dims[1]-2) ? MaxBoundary : Interior);
+  zLoc = (slice >= (this->Dims[2]-2) ? MaxBoundary : Interior);
+  yzLoc = (yLoc << 2) | (zLoc << 4);
+
+  // The trim edges may need adjustment if the contour travels between rows
+  // of x-edges (without intersecting these x-edges). This means checking
+  // whether the trim faces at (xL,xR) made up of the y-z edges intersect the
+  // contour. Basically just an intersection operation. Determine the voxel
+  // row trim edges, need to check all four x-edges.
+  vtkIdType xL=eMD[0][4], xR=eMD[0][5];
+  vtkIdType i;
+  if ( xInts )
+    {
+    for (i=1; i < 4; ++i)
+      {
+      xL = ( eMD[i][4] < xL ? eMD[i][4] : xL);
+      xR = ( eMD[i][5] > xR ? eMD[i][5] : xR);
+      }
+
+    if ( xL > 0 ) //if trimmed in the -x direction
+      {
+      ec0 = *(ePtr[0]+xL); ec1 = *(ePtr[1]+xL);
+      ec2 = *(ePtr[2]+xL); ec3 = *(ePtr[3]+xL);
+      if ( (ec0 & 0x1) != (ec1 & 0x1) || (ec1 & 0x1) != (ec2 & 0x1) ||
+           (ec2 & 0x1) != (ec3 & 0x1) )
+        {
+        xL = eMD[0][4] = 0; //reset left trim
+        }
+      }
+
+    if ( xR < (this->Dims[0]-1) ) //if trimmed in the +x direction
+      {
+      ec0 = *(ePtr[0]+xR); ec1 = *(ePtr[1]+xR);
+      ec2 = *(ePtr[2]+xR); ec3 = *(ePtr[3]+xR);
+      if ( (ec0 & 0x2) != (ec1 & 0x2) || (ec1 & 0x2) != (ec2 & 0x2) ||
+           (ec2 & 0x2) != (ec3 & 0x2) )
+        {
+        xR = eMD[0][5] = this->Dims[0]-1; //reset right trim
+        }
+      }
+    }
+  else //contour cuts through without intersecting x-edges, reset trim edges
+    {
+    xL = eMD[0][4] = 0;
+    xR = eMD[0][5] = this->Dims[0]-1;
+    }
+
+  // Okay run along the x-voxels and count the number of y- and
+  // z-intersections. Here we are just checking y,z edges that make up the
+  // voxel axes. Also check the number of primitives generated.
+  unsigned char *edgeUses, eCase, numTris;
+  ePtr[0] += xL; ePtr[1] += xL; ePtr[2] += xL; ePtr[3] += xL;
+  for (i=xL; i < xR; ++i) //run along the trimmed x-voxels
+    {
+    eCase = this->GetEdgeCase(ePtr);
+    if ( (numTris=this->GetNumberOfPrimitives(eCase)) > 0 )
+      {
+      // Okay let's increment the triangle count. But only if the voxel
+      // is valid and primitives are to be generated.
+      if ( this->GeneratePrimitives(ePtr) )
+        {
+        eMD[0][3] += numTris;
+        }
+
+      // Count the number of y- and z-points to be generated. Pass# 1 counted
+      // the number of x-intersections along the x-edges. Now we count all
+      // intersections on the y- and z-voxel axes.
+      edgeUses = this->GetEdgeUses(eCase);
+      eMD[0][1] += edgeUses[4]; //y-voxel axes edge always counted
+      eMD[0][2] += edgeUses[8]; //z-voxel axes edge always counted
+      loc = yzLoc | (i >= (this->Dims[0]-2) ? MaxBoundary : Interior);
+      if ( loc != 0 )
+        {
+        this->CountBoundaryYZInts(loc,edgeUses,eMD);
+        }
+      }//if cell contains contour
+
+    // advance the four pointers along voxel row
+    ePtr[0]++; ePtr[1]++; ePtr[2]++; ePtr[3]++;
+    }//for all voxels along this x-edge
+}
+
+//----------------------------------------------------------------------------
+// PASS 4: Process the x-row cells to generate output primitives, including
+// point coordinates and triangles. This is the fourth and final pass of the
+// algorithm.
+template <class T> void vtkExtractSurfaceAlgorithm<T>::
+GenerateOutput(double value, T* rowPtr, vtkIdType row, vtkIdType slice)
+{
+  // Grab the edge meta data surrounding the voxel row.
+  vtkIdType *eMD[4];
+  eMD[0] = this->EdgeMetaData + (slice*this->Dims[1] + row)*6; //this x-edge
+  eMD[1] = eMD[0] + 6; //x-edge in +y direction
+  eMD[2] = eMD[0] + this->Dims[1]*6; //x-edge in +z direction
+  eMD[3] = eMD[2] + 6; //x-edge in +y+z direction
+
+  // Return if there is nothing to do (i.e., no triangles to generate)
+  if ( eMD[0][3] == eMD[1][3] )
+    {
+    return;
+    }
+
+  // Get the voxel row trim edges and prepare to generate. Find the voxel row
+  // trim edges, need to check all four x-edges to compute row trim edge.
+  vtkIdType xL=eMD[0][4], xR=eMD[0][5];
+  vtkIdType i;
+  for (i=1; i < 4; ++i)
+    {
+    xL = ( eMD[i][4] < xL ? eMD[i][4] : xL);
+    xR = ( eMD[i][5] > xR ? eMD[i][5] : xR);
+    }
+
+  // Grab the four edge cases bounding this voxel x-row. Begin at left trim edge.
+  unsigned char *ePtr[4];
+  ePtr[0] = this->XCases + slice*this->SliceOffset + row*(this->Dims[0]-1) + xL;
+  ePtr[1] = ePtr[0] + this->Dims[0]-1;
+  ePtr[2] = ePtr[0] + this->SliceOffset;
+  ePtr[3] = ePtr[2] + this->Dims[0]-1;
+
+  // Traverse all voxels in this row, those containing the contour are
+  // further identified for processing, meaning generating points and
+  // triangles. Begin by setting up point ids on voxel edges.
+  vtkIdType triId = eMD[0][3];
+  vtkIdType eIds[12]; //the ids of generated points
+
+  unsigned char eCase = this->InitVoxelIds(ePtr,eMD,eIds);
+
+  // Determine the proximity to the boundary of volume. This information is
+  // used to generate edge intersections.
+  unsigned char loc, yLoc, zLoc, yzLoc;
+  yLoc = (row < 1 ? MinBoundary :
+          (row >= (this->Dims[1]-2) ? MaxBoundary : Interior));
+  zLoc = (slice < 1 ? MinBoundary :
+          (slice >= (this->Dims[2]-2) ? MaxBoundary : Interior));
+  yzLoc = (yLoc << 2) | (zLoc << 4);
+
+  // Run along voxels in x-row direction and generate output primitives. Note
+  // that active voxel axes edges are interpolated to produce points and
+  // possibly interpolate attribute data.
+  float x[3];
+  x[0] = this->Origin[0] + xL*this->Spacing[0];
+  x[1] = this->Origin[1] + row*this->Spacing[1];
+  x[2] = this->Origin[2] + slice*this->Spacing[2];
+
+  //compute the ijk for this section
+  vtkIdType ijk[3] = { xL, row, slice};
+
+  //load the inc0/inc1/inc2 into local memory
+  const int incs[3] = { this->Inc0, this->Inc1, this->Inc2 };
+  const T* sPtr = rowPtr + xL*incs[0];
+
+  for (i=xL; i < xR; ++i)
+    {
+    const unsigned char numTris = this->GetNumberOfPrimitives(eCase);
+    if ( numTris > 0 )
+      {
+      // Start by generating triangles for this case
+      if ( this->GeneratePrimitives(ePtr) )
+        {
+        this->GenerateTris(eCase,numTris,eIds,triId);
+        }
+
+      // Now generate point(s) along voxel axes if needed. Remember to take
+      // boundary into account.
+      loc = yzLoc | (i < 1 ? MinBoundary :
+          (i >= (this->Dims[0]-2) ? MaxBoundary : Interior));
+      if ( this->CaseIncludesAxes(eCase) || loc != Interior )
+        {
+        unsigned char const * const edgeUses = this->GetEdgeUses(eCase);
+        this->GeneratePoints(value, loc, ijk,
+                             sPtr, incs,
+                             x, edgeUses, eIds);
+        }
+      this->AdvanceVoxelIds(eCase,eIds);
+      }
+
+    // advance along voxel row
+    ePtr[0]++; ePtr[1]++; ePtr[2]++; ePtr[3]++;
+    eCase = this->GetEdgeCase(ePtr);
+
+    ++ijk[0];
+    sPtr += incs[0];
+    x[0]+= this->Spacing[0];
+    } //for all non-trimmed cells along this x-edge
+}
+
+//----------------------------------------------------------------------------
+// Contouring filter specialized for 3D volumes. This templated function
+// interfaces the vtkExtractSurface class with the templated algorithm
+// class. It also invokes the three passes of the Flying Edges algorithm.
+template <class T> void vtkExtractSurfaceAlgorithm<T>::
+Contour(vtkExtractSurface *self, vtkImageData *input, int extent[6],
+        vtkIdType *incs, T *scalars, vtkPoints *newPts, vtkCellArray *newTris,
+        vtkFloatArray *newNormals, vtkFloatArray *newGradients)
+{
+  double value;
+  int numContours = 1;
+  vtkIdType vidx, row, slice, *eMD, zInc;
+  vtkIdType numOutXPts, numOutYPts, numOutZPts, numOutTris;
+  vtkIdType numXPts=0, numYPts=0, numZPts=0, numTris=0;
+  vtkIdType startXPts, startYPts, startZPts, startTris;
+  startXPts = startYPts = startZPts = startTris = 0;
+
+  // This may be subvolume of the total 3D image. Capture information for
+  // subsequent processing.
+  vtkExtractSurfaceAlgorithm<T> algo;
+  algo.Scalars = scalars;
+  algo.Radius = self->GetRadius();
+  input->GetOrigin(algo.Origin);
+  input->GetSpacing(algo.Spacing);
+  algo.Min0 = extent[0];
+  algo.Max0 = extent[1];
+  algo.Inc0 = incs[0];
+  algo.Min1 = extent[2];
+  algo.Max1 = extent[3];
+  algo.Inc1 = incs[1];
+  algo.Min2 = extent[4];
+  algo.Max2 = extent[5];
+  algo.Inc2 = incs[2];
+  algo.AdjustOrigin();
+
+  // Now allocate working arrays. The XCases array tracks x-edge cases.
+  algo.Dims[0] = algo.Max0 - algo.Min0 + 1;
+  algo.Dims[1] = algo.Max1 - algo.Min1 + 1;
+  algo.Dims[2] = algo.Max2 - algo.Min2 + 1;
+  algo.NumberOfEdges = algo.Dims[1]*algo.Dims[2];
+  algo.SliceOffset = (algo.Dims[0]-1) * algo.Dims[1];
+  algo.XCases = new unsigned char [(algo.Dims[0]-1)*algo.NumberOfEdges];
+
+  // Also allocate the characterization (metadata) array for the x edges.
+  // This array tracks the number of x-, y- and z- intersections on the voxel
+  // axes along an x-edge; as well as the number of the output triangles, and
+  // the xMin_i and xMax_i (minimum index of first intersection, maximum
+  // index of intersection for the ith x-row, the so-called trim edges used
+  // for computational trimming).
+  algo.EdgeMetaData = new vtkIdType [algo.NumberOfEdges*6];
+
+  // Loop across each contour value. This encompasses all three passes.
+  for (vidx = 0; vidx < numContours; vidx++)
+    {
+    value = 0.0; //single pass, zero-crossing isosurface
+
+    // PASS 1: Traverse all x-rows building edge cases and counting number of
+    // intersections (i.e., accumulate information necessary for later output
+    // memory allocation, e.g., the number of output points along the x-rows
+    // are counted).
+    Pass1<T> pass1(&algo,value);
+    vtkSMPTools::For(0,algo.Dims[2], pass1);
+
+    // PASS 2: Traverse all voxel x-rows and process voxel y&z edges.  The
+    // result is a count of the number of y- and z-intersections, as well as
+    // the number of triangles generated along these voxel rows.
+    Pass2<T> pass2(&algo);
+    vtkSMPTools::For(0,algo.Dims[2]-1, pass2);
+
+    // PASS 3: Now allocate and generate output. First we have to update the
+    // edge meta data to partition the output into separate pieces so
+    // independent threads can write without collisions. Once allocation is
+    // complete, the volume is processed on a voxel row by row basis to
+    // produce output points and triangles, and interpolate point attribute
+    // data (as necessary). NOTE: This implementation is serial. It is
+    // possible to use a threaded prefix sum to make it even faster. Since
+    // this pass usually takes a small amount of time, we choose simplicity
+    // over performance.
+    numOutXPts = startXPts;
+    numOutYPts = startYPts;
+    numOutZPts = startZPts;
+    numOutTris = startTris;
+
+    // Count number of points and tris generate along each cell row
+    for (slice=0; slice < algo.Dims[2]; ++slice)
+      {
+      zInc = slice * algo.Dims[1];
+      for (row=0; row < algo.Dims[1]; ++row)
+        {
+        eMD = algo.EdgeMetaData + (zInc+row)*6;
+        numXPts = eMD[0];
+        numYPts = eMD[1];
+        numZPts = eMD[2];
+        numTris = eMD[3];
+        eMD[0] = numOutXPts + numOutYPts + numOutZPts;
+        eMD[1] = eMD[0] + numXPts;
+        eMD[2] = eMD[1] + numYPts;
+        eMD[3] = numOutTris;
+        numOutXPts += numXPts;
+        numOutYPts += numYPts;
+        numOutZPts += numZPts;
+        numOutTris += numTris;
+        }
+      }
+
+    // Output can now be allocated.
+    vtkIdType totalPts = numOutXPts + numOutYPts + numOutZPts;
+    if ( totalPts > 0 )
+      {
+      newPts->GetData()->WriteVoidPointer(0,3*totalPts);
+      algo.NewPoints = static_cast<float*>(newPts->GetVoidPointer(0));
+      newTris->WritePointer(numOutTris,4*numOutTris);
+      algo.NewTris = static_cast<vtkIdType*>(newTris->GetPointer());
+
+      if (newGradients)
+        {
+        newGradients->WriteVoidPointer(0,3*totalPts);
+        algo.NewGradients = static_cast<float*>(newGradients->GetVoidPointer(0));
+        }
+      if (newNormals)
+        {
+        newNormals->WriteVoidPointer(0,3*totalPts);
+        algo.NewNormals = static_cast<float*>(newNormals->GetVoidPointer(0));
+        }
+      algo.NeedGradients = (algo.NewGradients || algo.NewNormals);
+
+      // PASS 4: Fourth and final pass: Process voxel rows and generate output.
+      // Note that we are simultaneously generating triangles and interpolating
+      // points. These could be split into separate, parallel operations for
+      // maximum performance.
+      Pass4<T> pass4(&algo,value);
+      vtkSMPTools::For(0,algo.Dims[2]-1, pass4);
+      }//if anything generated
+
+    // Handle multiple contours
+    startXPts = numOutXPts;
+    startYPts = numOutYPts;
+    startZPts = numOutZPts;
+    startTris = numOutTris;
+    }// for all contour values
+
+  // Clean up and return
+  delete [] algo.XCases;
+  delete [] algo.EdgeMetaData;
+}
+
+//----------------------------------------------------------------------------
+// Here is the VTK class proper.
+// Construct object with a single contour value of 0.0.
+vtkExtractSurface::vtkExtractSurface()
+{
+  this->Radius = 0.1;
+  this->HoleFilling = false;
+  this->ComputeNormals = 1;
+  this->ComputeGradients = 0;
+
+  // by default process active point scalars
+  this->SetInputArrayToProcess(0,0,0,vtkDataObject::FIELD_ASSOCIATION_POINTS,
+                               vtkDataSetAttributes::SCALARS);
+}
+
+//----------------------------------------------------------------------------
+vtkExtractSurface::~vtkExtractSurface()
+{
+}
+
+//----------------------------------------------------------------------------
+int vtkExtractSurface::RequestUpdateExtent(
+  vtkInformation *vtkNotUsed(request),
+  vtkInformationVector **inputVector,
+  vtkInformationVector *outputVector)
+{
+  // These require extra ghost levels
+  if (this->ComputeGradients || this->ComputeNormals)
+    {
+    vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
+    vtkInformation *outInfo = outputVector->GetInformationObject(0);
+
+    int ghostLevels;
+    ghostLevels =
+      outInfo->Get(
+        vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS());
+    inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS(),
+                ghostLevels + 1);
+    }
+
+  return 1;
+}
+
+//----------------------------------------------------------------------------
+int vtkExtractSurface::RequestData(
+  vtkInformation *request,
+  vtkInformationVector **inputVector,
+  vtkInformationVector *outputVector)
+{
+   vtkDebugMacro(<< "Executing 3D structured contour");
+
+  // get the info objects
+  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
+  vtkInformation *outInfo = outputVector->GetInformationObject(0);
+
+  // get the input and output
+  vtkImageData *input = vtkImageData::SafeDownCast(
+    inInfo->Get(vtkDataObject::DATA_OBJECT()));
+  vtkPolyData *output = vtkPolyData::SafeDownCast(
+    outInfo->Get(vtkDataObject::DATA_OBJECT()));
+
+  // to be safe recompute the update extent
+  this->RequestUpdateExtent(request,inputVector,outputVector);
+  vtkDataArray *inScalars = this->GetInputArrayToProcess(0,inputVector);
+
+  // Determine extent
+  int* inExt = input->GetExtent();
+  int exExt[6];
+  inInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT(), exExt);
+  for (int i=0; i<3; i++)
+    {
+    if (inExt[2*i] > exExt[2*i])
+      {
+      exExt[2*i] = inExt[2*i];
+      }
+    if (inExt[2*i+1] < exExt[2*i+1])
+      {
+      exExt[2*i+1] = inExt[2*i+1];
+      }
+    }
+  if ( exExt[0] >= exExt[1] || exExt[2] >= exExt[3] || exExt[4] >= exExt[5] )
+    {
+    vtkDebugMacro(<<"3D structured contours requires 3D data");
+    return 0;
+    }
+
+  // Check data type and execute appropriate function
+  //
+  if (inScalars == NULL)
+    {
+    vtkDebugMacro("No scalars for contouring.");
+    return 0;
+    }
+
+  // Create necessary objects to hold output. We will defer the
+  // actual allocation to a later point.
+  vtkCellArray *newTris = vtkCellArray::New();
+  vtkPoints *newPts = vtkPoints::New();
+  newPts->SetDataTypeToFloat();
+  vtkFloatArray *newNormals = NULL;
+  vtkFloatArray *newGradients = NULL;
+
+  if (this->ComputeNormals)
+    {
+    newNormals = vtkFloatArray::New();
+    newNormals->SetNumberOfComponents(3);
+    newNormals->SetName("Normals");
+    }
+  if (this->ComputeGradients)
+    {
+    newGradients = vtkFloatArray::New();
+    newGradients->SetNumberOfComponents(3);
+    newGradients->SetName("Gradients");
+    }
+
+  void *ptr = input->GetArrayPointerForExtent(inScalars, exExt);
+  vtkIdType *incs = input->GetIncrements();
+  switch (inScalars->GetDataType())
+    {
+    vtkTemplateMacro(vtkExtractSurfaceAlgorithm<VTK_TT>::
+                     Contour(this, input, exExt, incs, (VTK_TT *)ptr,
+                             newPts, newTris, newNormals, newGradients));
+    }
+
+  vtkDebugMacro(<<"Created: "
+                << newPts->GetNumberOfPoints() << " points, "
+                << newTris->GetNumberOfCells() << " triangles");
+
+  // Update ourselves.  Because we don't know up front how many lines
+  // we've created, take care to reclaim memory.
+  output->SetPoints(newPts);
+  newPts->Delete();
+
+  output->SetPolys(newTris);
+  newTris->Delete();
+
+  if (newNormals)
+    {
+    int idx = output->GetPointData()->AddArray(newNormals);
+    output->GetPointData()->SetActiveAttribute(idx, vtkDataSetAttributes::NORMALS);
+    newNormals->Delete();
+    }
+
+  if (newGradients)
+    {
+    int idx = output->GetPointData()->AddArray(newGradients);
+    output->GetPointData()->SetActiveAttribute(idx, vtkDataSetAttributes::VECTORS);
+    newGradients->Delete();
+    }
+
+  return 1;
+}
+
+//----------------------------------------------------------------------------
+int vtkExtractSurface::FillInputPortInformation(int, vtkInformation *info)
+{
+  info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkImageData");
+  return 1;
+}
+
+//----------------------------------------------------------------------------
+void vtkExtractSurface::PrintSelf(ostream& os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os,indent);
+
+  os << indent << "Radius: " << this->Radius << "\n";
+  os << indent << "Hole Filling: " << (this->HoleFilling ? "On\n" : "Off\n");
+  os << indent << "Compute Normals: " << (this->ComputeNormals ? "On\n" : "Off\n");
+  os << indent << "Compute Gradients: " << (this->ComputeGradients ? "On\n" : "Off\n");
+}
diff --git a/Filters/Points/vtkExtractSurface.h b/Filters/Points/vtkExtractSurface.h
new file mode 100644
index 0000000000000000000000000000000000000000..cd9749983b37a10af90b31d1bd590eca0e2498f5
--- /dev/null
+++ b/Filters/Points/vtkExtractSurface.h
@@ -0,0 +1,158 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkExtractSurface.h
+
+  Copyright (c) Kitware, Inc.
+  All rights reserved.
+  See LICENSE file 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.
+
+=========================================================================*/
+// .NAME vtkExtractSurface - generate zero-crossing isosurface from
+// truncated signed distance volume
+
+// .SECTION Description
+// This filter extracts the zero-crossing isosurface from a truncated signed
+// distance function TSDF. The TSDF is sampled across a volume, and is
+// extracted using a modified version of the Flying Edges algorithm for
+// increased speed, and to support multithreading. To use the filter, an
+// input volume should be assigned, which may have special values indicating
+// empty and/or unseen portions of the volume. These values are equal to +/-
+// radius value of the signed distance function, and should be consistent
+// with any filters used to generate the input volume (e.g.,
+// vtkSignedDistance).
+//
+// The Flying Edges algorithm is modified to deal with the nature of the
+// truncated, signed distance function. Being truncated, the distance
+// function typically is not computed throughout the volume, rather the
+// special data values "unseen" and/or "empty" maybe assigned to distant or
+// bordering voxels. The implications of this are that this implementation
+// may produce non-closed, non-manifold surfaces, which is what is needed
+// to extract surfaces.
+//
+// More specifically, voxels may exist in one of three states: 1) within the
+// TSDF, which extends +/-Radius from a generating geometry (typically a
+// point cloud); 2) in the empty state, in which it is known that the surface
+// does not exist; and 3) the unseen state, where a surface may exist but not
+// enough information is known to be certain. Such situations arise, for
+// example, when laser scanners generate point clouds, and the propagation of
+// the laser beam "carves" out regions where no geometry exists (thereby
+// defining empty space). Furthermore, areas in which the beam are occluded
+// by geometry are known as "unseen" and the boundary between empty and
+// unseen can be processed to produced a portion of the output isosurface
+// (this is called hole filling).
+
+// .SECTION Caveats
+// This class has been threaded with vtkSMPTools. Using TBB or other
+// non-sequential type (set in the CMake variable
+// VTK_SMP_IMPLEMENTATION_TYPE) may improve performance significantly.
+//
+// <pre>
+// Notes on the implementation:
+// 1. This is a lightly modified version of vtkFlyingEdges3D. Some design goals
+//    included minimizing the impact on the FE algorithm, and not adding extra
+//    memory requirements.
+// 2. It presumes an isocontour value=0.0  (the zero crossing of a signed
+//    distance function).
+// 3. The major modifications are to the edge cases. In Flying Edges, a single
+//    byte represents the case of an edge, and within that byte only 2 bits
+//    are needed (the extra six bytes are not used). Here, these unused bytes
+//    are repurposed to represent the "state" of the edge, whether it is
+//    1) near to the TSDF; 2) in an empty state; or 3) unseen state.
+// 4. Since these now-used bits encode extra state information, masking and
+//    related methods are used to tease apart the edge cases from the edge
+//    state.
+// 5. Voxels with edges marked "empty" are not processed, i.e., no output
+//    triangle primitives are generated. Depending on whether hole filling is
+//    enabled, voxels with edges marked "unseen" may not be processed either.
+// 6. As a result of #1 and #5, and the desire to keep the implementation simple,
+//    it is possible to produce output points which are not attached to any output
+//    triangle.
+//</pre>
+//
+// This algorithm loosely follows the most excellent paper by Curless and
+// Levoy: "A Volumetric Method for Building Complex Models from Range
+// Images."
+
+// .SECTION See Also
+// vtkSignedDistance vtkFlyingEdges3D
+
+#ifndef vtkExtractSurface_h
+#define vtkExtractSurface_h
+
+#include "vtkFiltersPointsModule.h" // For export macro
+#include "vtkPolyDataAlgorithm.h"
+#include "vtkContourValues.h" // Passes calls through
+
+class vtkImageData;
+
+class VTKFILTERSPOINTS_EXPORT vtkExtractSurface : public vtkPolyDataAlgorithm
+{
+public:
+  // Description:
+  // Standard methods for instantiating the class, providing type information,
+  // and printing.
+  static vtkExtractSurface *New();
+  vtkTypeMacro(vtkExtractSurface,vtkPolyDataAlgorithm);
+  void PrintSelf(ostream& os, vtkIndent indent);
+
+  // Description:
+  // Specify the radius of influence of the signed distance function. Data
+  // values (which are distances) that are greater than or equal to the
+  // radius (i.e., d >= Radius) are considered unseen voxels; those voxel
+  // data values d <= -Radius are considered empty voxels.
+  vtkSetClampMacro(Radius,double,0.0,VTK_FLOAT_MAX);
+  vtkGetMacro(Radius,double);
+
+  // Description:
+  // Enable hole filling. This generates separating surfaces between the
+  // empty and unseen portions of the volume.
+  vtkSetMacro(HoleFilling,bool);
+  vtkGetMacro(HoleFilling,bool);
+  vtkBooleanMacro(HoleFilling,bool);
+
+  // Description:
+  // Set/Get the computation of normals. Normal computation is fairly
+  // expensive in both time and storage. If the output data will be processed
+  // by filters that modify topology or geometry, it may be wise to turn
+  // Normals and Gradients off.
+  vtkSetMacro(ComputeNormals,int);
+  vtkGetMacro(ComputeNormals,int);
+  vtkBooleanMacro(ComputeNormals,int);
+
+  // Description:
+  // Set/Get the computation of gradients. Gradient computation is fairly
+  // expensive in both time and storage. Note that if ComputeNormals is on,
+  // gradients will have to be calculated, but will not be stored in the
+  // output dataset. If the output data will be processed by filters that
+  // modify topology or geometry, it may be wise to turn Normals and
+  // Gradients off.
+  vtkSetMacro(ComputeGradients,int);
+  vtkGetMacro(ComputeGradients,int);
+  vtkBooleanMacro(ComputeGradients,int);
+
+protected:
+  vtkExtractSurface();
+  ~vtkExtractSurface();
+
+  double Radius;
+  bool HoleFilling;
+  int ComputeNormals;
+  int ComputeGradients;
+
+  virtual int RequestData(vtkInformation *, vtkInformationVector **,
+                          vtkInformationVector *);
+  virtual int RequestUpdateExtent(vtkInformation *, vtkInformationVector **,
+                                  vtkInformationVector *);
+  virtual int FillInputPortInformation(int port, vtkInformation *info);
+
+private:
+  vtkExtractSurface(const vtkExtractSurface&) VTK_DELETE_FUNCTION;
+  void operator=(const vtkExtractSurface&) VTK_DELETE_FUNCTION;
+};
+
+#endif
diff --git a/Filters/Points/vtkFitImplicitFunction.cxx b/Filters/Points/vtkFitImplicitFunction.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..f6fc04110f8eb574508f18a16386447b2c002699
--- /dev/null
+++ b/Filters/Points/vtkFitImplicitFunction.cxx
@@ -0,0 +1,141 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkFitImplicitFunction.cxx
+
+  Copyright (c) Kitware, Inc.
+  All rights reserved.
+  See LICENSE file 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.
+
+=========================================================================*/
+#include "vtkFitImplicitFunction.h"
+
+#include "vtkObjectFactory.h"
+#include "vtkPointSet.h"
+#include "vtkPoints.h"
+#include "vtkImplicitFunction.h"
+#include "vtkSMPTools.h"
+
+vtkStandardNewMacro(vtkFitImplicitFunction);
+vtkCxxSetObjectMacro(vtkFitImplicitFunction,ImplicitFunction,vtkImplicitFunction);
+
+//----------------------------------------------------------------------------
+// Helper classes to support efficient computing, and threaded execution.
+namespace {
+
+//----------------------------------------------------------------------------
+// The threaded core of the algorithm
+template <typename T>
+struct ExtractPoints
+{
+  const T *Points;
+  vtkImplicitFunction *Function;
+  double Threshold;
+  vtkIdType *PointMap;
+
+  ExtractPoints(T *points, vtkImplicitFunction *f, double thresh, vtkIdType *map) :
+    Points(points), Function(f), Threshold(thresh), PointMap(map)
+    {
+    }
+
+  void operator() (vtkIdType ptId, vtkIdType endPtId)
+    {
+      const T *p = this->Points + 3*ptId;
+      vtkIdType *map = this->PointMap + ptId;
+      vtkImplicitFunction *f = this->Function;
+      double x[3], val;
+      double tMin = (-this->Threshold);
+      double tMax = this->Threshold;
+
+      for ( ; ptId < endPtId; ++ptId)
+        {
+        x[0] = static_cast<double>(*p++);
+        x[1] = static_cast<double>(*p++);
+        x[2] = static_cast<double>(*p++);
+
+        val = f->FunctionValue(x);
+        *map++ = ( (val >= tMin && val < tMax) ? 1 : -1 );
+        }
+    }
+
+  static void Execute(vtkFitImplicitFunction *self, vtkIdType numPts,
+                      T *points, vtkIdType *map)
+    {
+      ExtractPoints extract(points, self->GetImplicitFunction(),
+                            self->GetThreshold(), map);
+      vtkSMPTools::For(0, numPts, extract);
+    }
+
+}; //ExtractPoints
+
+} //anonymous namespace
+
+//================= Begin class proper =======================================
+//----------------------------------------------------------------------------
+vtkFitImplicitFunction::vtkFitImplicitFunction()
+{
+  this->ImplicitFunction = NULL;
+  this->Threshold = 0.01;
+}
+
+//----------------------------------------------------------------------------
+vtkFitImplicitFunction::~vtkFitImplicitFunction()
+{
+  this->SetImplicitFunction(NULL);
+}
+
+//----------------------------------------------------------------------------
+// Overload standard modified time function. If implicit function is modified,
+// then this object is modified as well.
+vtkMTimeType vtkFitImplicitFunction::GetMTime()
+{
+  vtkMTimeType mTime=this->MTime.GetMTime();
+  vtkMTimeType impFuncMTime;
+
+  if ( this->ImplicitFunction != NULL )
+    {
+    impFuncMTime = this->ImplicitFunction->GetMTime();
+    mTime = ( impFuncMTime > mTime ? impFuncMTime : mTime );
+    }
+
+  return mTime;
+}
+
+//----------------------------------------------------------------------------
+// Traverse all the input points and extract those that lie near the surface
+// of an implicit function.
+int vtkFitImplicitFunction::FilterPoints(vtkPointSet *input)
+{
+  // Check the input.
+  if ( !this->ImplicitFunction )
+    {
+    vtkErrorMacro(<<"Implicit function required\n");
+    return 0;
+    }
+
+  // Determine which points, if any, should be removed. We create a map
+  // to keep track. The bulk of the algorithmic work is done in this pass.
+  vtkIdType numPts = input->GetNumberOfPoints();
+  void *inPtr = input->GetPoints()->GetVoidPointer(0);
+  switch (input->GetPoints()->GetDataType())
+    {
+    vtkTemplateMacro(ExtractPoints<VTK_TT>::
+                     Execute(this, numPts, (VTK_TT *)inPtr, this->PointMap));
+    }
+
+  return 1;
+}
+
+//----------------------------------------------------------------------------
+void vtkFitImplicitFunction::PrintSelf(ostream& os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os,indent);
+
+  os << indent << "Implicit Function: "
+     << static_cast<void *>(this->ImplicitFunction) << "\n";
+  os << indent << "Threshold: " << this->Threshold << "\n";
+}
diff --git a/Filters/Points/vtkFitImplicitFunction.h b/Filters/Points/vtkFitImplicitFunction.h
new file mode 100644
index 0000000000000000000000000000000000000000..aa3045e45c9590f850a621361eda44e69219aefa
--- /dev/null
+++ b/Filters/Points/vtkFitImplicitFunction.h
@@ -0,0 +1,103 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkFitImplicitFunction.h
+
+  Copyright (c) Kitware, Inc.
+  All rights reserved.
+  See LICENSE file 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.
+
+=========================================================================*/
+// .NAME vtkFitImplicitFunction - extract points on the surface of an implicit function
+
+// .SECTION Description
+// vtkFitImplicitFunction extract points that are on the surface of an
+// implicit function (within some threshold). Implicit functions in VTK are
+// any function of the form f(x,y,z)=c, where values c==0 are considered the
+// surface of the implicit function. Typical examples of implicit functions
+// include planes, spheres, cylinders, cones, etc. plus boolean combinations
+// of these functions. In this implementation, a threshold is used to create
+// a fuzzy region considered "on" the surface. In essence, this is a very
+// poor man's RANSAC algorithm, where the user picks a function on which to
+// fit some points. Thus it is possible to use this filter to define a
+// proposed model and place it into an optimization loop to best fit it to a
+// set of points.
+//
+// Note that while any vtkPointSet type can be provided as input, the output is
+// represented by an explicit representation of points via a
+// vtkPolyData. This output polydata will populate its instance of vtkPoints,
+// but no cells will be defined (i.e., no vtkVertex or vtkPolyVertex are
+// contained in the output). Also, after filter execution, the user can
+// request a vtkIdType* map which indicates how the input points were mapped
+// to the output. A value of map[i] (where i is the ith input point) less
+// than 0 means that the ith input point was removed. (See also the
+// superclass documentation for accessing the removed points through the
+// filter's second output.)
+
+// .SECTION Caveats
+// This class has been threaded with vtkSMPTools. Using TBB or other
+// non-sequential type (set in the CMake variable
+// VTK_SMP_IMPLEMENTATION_TYPE) may improve performance significantly.
+
+// .SECTION See Also
+// vtkPointCloudFilter vtkExtractPoints vtkImplicitFunction
+
+#ifndef vtkFitImplicitFunction_h
+#define vtkFitImplicitFunction_h
+
+#include "vtkFiltersPointsModule.h" // For export macro
+#include "vtkPointCloudFilter.h"
+
+class vtkImplicitFunction;
+class vtkPointSet;
+
+
+class VTKFILTERSPOINTS_EXPORT vtkFitImplicitFunction : public vtkPointCloudFilter
+{
+public:
+  // Description:
+  // Standard methods for instantiating, obtaining type information, and
+  // printing information.
+  static vtkFitImplicitFunction *New();
+  vtkTypeMacro(vtkFitImplicitFunction,vtkPointCloudFilter);
+  void PrintSelf(ostream& os, vtkIndent indent);
+
+  // Description:
+  // Specify the implicit function defining a surface on which points
+  // are to be extracted.
+  virtual void SetImplicitFunction(vtkImplicitFunction*);
+  vtkGetObjectMacro(ImplicitFunction,vtkImplicitFunction);
+
+  // Description:
+  // Specify a threshold value which defines a fuzzy extraction surface.
+  // Since in this filter the implicit surface is defined as f(x,y,z)=0;
+  // the extracted points are (-Threshold <= f(x,y,z) < Threshold).
+  vtkSetClampMacro(Threshold,double,0.0,VTK_FLOAT_MAX);
+  vtkGetMacro(Threshold,double);
+
+  // Description:
+  // Return the MTime taking into account changes to the implicit function.
+  virtual vtkMTimeType GetMTime();
+
+protected:
+  vtkFitImplicitFunction();
+  ~vtkFitImplicitFunction();
+
+  vtkImplicitFunction *ImplicitFunction;
+  double Threshold;
+
+  // All derived classes must implement this method. Note that a side effect of
+  // the class is to populate the PointMap. Zero is returned if there is a failure.
+  virtual int FilterPoints(vtkPointSet *input);
+
+private:
+  vtkFitImplicitFunction(const vtkFitImplicitFunction&) VTK_DELETE_FUNCTION;
+  void operator=(const vtkFitImplicitFunction&) VTK_DELETE_FUNCTION;
+
+};
+
+#endif
diff --git a/Filters/Points/vtkHierarchicalBinningFilter.cxx b/Filters/Points/vtkHierarchicalBinningFilter.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..dd413d74da1c59c22bc12024a5355755eedcfd08
--- /dev/null
+++ b/Filters/Points/vtkHierarchicalBinningFilter.cxx
@@ -0,0 +1,922 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkHierarchicalBinningFilter.cxx
+
+  Copyright (c) Kitware, Inc.
+  All rights reserved.
+  See LICENSE file 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.
+
+=========================================================================*/
+#include "vtkHierarchicalBinningFilter.h"
+
+#include "vtkObjectFactory.h"
+#include "vtkPointSet.h"
+#include "vtkPoints.h"
+#include "vtkIntArray.h"
+#include "vtkIdTypeArray.h"
+#include "vtkDoubleArray.h"
+#include "vtkPointData.h"
+#include "vtkFieldData.h"
+#include "vtkInformation.h"
+#include "vtkInformationVector.h"
+#include "vtkMath.h"
+#include "vtkSMPTools.h"
+
+vtkStandardNewMacro(vtkHierarchicalBinningFilter);
+
+namespace {
+
+//-----------------------------------------------------------------------------
+// Number ^ index: power function for integers.
+static int power(int number, int level)
+{
+  if (level == 0)
+    {
+    return 1;
+    }
+  int num = number;
+  for (int i = 1; i < level; i++)
+    {
+    number = number * num;
+    }
+  return number;
+}
+
+//----------------------------------------------------------------------------
+static int GetLevelOffset(int level, int divs[3])
+{
+  int block = divs[0] * divs[1] * divs[2];
+  int offset = 0;
+  for (int i=0; i<level; ++i)
+    {
+    offset += power( block, i);
+    }
+  return offset;
+}
+
+//-----------------------------------------------------------------------------
+// The hierarchy of uniform subdivided binning grids.
+struct UniformBinning
+{
+  int Level;
+  int Divs[3];
+  double Bounds[6];
+  int NumBins; //number of bins in this level of the tree
+  int LevelOffset; //offset from root bin
+
+  // These are internal data members used for performance reasons
+  double H[3];
+  double hX, hY, hZ;
+  double fX, fY, fZ, bX, bY, bZ;
+  vtkIdType xD, yD, zD, xyD;
+
+  // Construction. Provide the current level, and the global binning
+  // divisions, and the global bounds.
+  UniformBinning(int level, int divs[3], double bounds[6])
+    {
+      this->Level = level;
+
+      this->Divs[0] = power( divs[0], level);
+      this->Divs[1] = power( divs[1], level);
+      this->Divs[2] = power( divs[2], level);
+      this->NumBins = this->Divs[0] * this->Divs[1] * this->Divs[2];
+
+      this->Bounds[0] = bounds[0];
+      this->Bounds[1] = bounds[1];
+      this->Bounds[2] = bounds[2];
+      this->Bounds[3] = bounds[3];
+      this->Bounds[4] = bounds[4];
+      this->Bounds[5] = bounds[5];
+
+      this->H[0] = (this->Bounds[1] - this->Bounds[0]) / static_cast<double>(this->Divs[0]);
+      this->H[1] = (this->Bounds[3] - this->Bounds[2]) / static_cast<double>(this->Divs[1]);
+      this->H[2] = (this->Bounds[5] - this->Bounds[4]) / static_cast<double>(this->Divs[2]);
+
+      this->LevelOffset = GetLevelOffset(level,divs);
+
+      // Setup internal data members for more efficient processing.
+      this->hX = this->H[0];
+      this->hY = this->H[1];
+      this->hZ = this->H[2];
+      this->fX = 1.0 / this->H[0];
+      this->fY = 1.0 / this->H[1];
+      this->fZ = 1.0 / this->H[2];
+      this->bX = this->Bounds[0];
+      this->bY = this->Bounds[2];
+      this->bZ = this->Bounds[4];
+      this->xD = this->Divs[0];
+      this->yD = this->Divs[1];
+      this->zD = this->Divs[2];
+      this->xyD = this->Divs[0] * this->Divs[1];
+    }
+
+
+  //-----------------------------------------------------------------------------
+  // Inlined for performance. These function invocations must be called after
+  // BuildLocator() is invoked, otherwise the output is indeterminate.
+  void GetBinIndices(const double *x, int ijk[3]) const
+    {
+    // Compute point index. Make sure it lies within range of locator.
+    ijk[0] = static_cast<int>(((x[0] - bX) * fX));
+    ijk[1] = static_cast<int>(((x[1] - bY) * fY));
+    ijk[2] = static_cast<int>(((x[2] - bZ) * fZ));
+
+    ijk[0] = (ijk[0] < 0 ? 0 : (ijk[0] >= xD ? xD-1 : ijk[0]));
+    ijk[1] = (ijk[1] < 0 ? 0 : (ijk[1] >= yD ? yD-1 : ijk[1]));
+    ijk[2] = (ijk[2] < 0 ? 0 : (ijk[2] >= zD ? zD-1 : ijk[2]));
+    }
+
+  //-----------------------------------------------------------------------------
+  // The bin offset is used to uniquefy the id across the hierarchy of binning grids
+  vtkIdType GetBinIndex(const double *x) const
+    {
+    int ijk[3];
+    this->GetBinIndices(x, ijk);
+    return (this->LevelOffset + ijk[0] + ijk[1]*xD + ijk[2]*xyD);
+    }
+
+  //-----------------------------------------------------------------------------
+  // Get the bounds for a particular bin at this level
+  void GetBinBounds(int localBin, double bounds[6])
+    {
+      int i = localBin % this->xD;
+      int j = (localBin / this->xD) % this->yD;
+      int k = localBin / this->xyD;
+      bounds[0] = this->Bounds[0] + i * hX;
+      bounds[1] = bounds[0] + this->hX;
+      bounds[2] = this->Bounds[2] + j * hY;
+      bounds[3] = bounds[2] + this->hY;
+      bounds[4] = this->Bounds[4] + k * hZ;
+      bounds[5] = bounds[4] + this->hZ;
+    }
+};
+
+} //anonymous namespace
+
+//-----------------------------------------------------------------------------
+// This non-templated class provides virtual functions to simplify the access
+// to the templated subclass. Note this is not in anonymous namespace because the
+// VTK class refers to it in the header file (PIMPLd).
+struct vtkBinTree
+{
+  vtkPoints *InPts; // the points to be binned
+  vtkIdType NumPts;
+
+  int NumLevels;
+  int Divs[3];
+  double Bounds[6];
+  UniformBinning  *Tree[VTK_MAX_LEVEL+1]; // a uniform binning for each level
+  int NumBins; // the total number of bins (from all levels) in the tree
+  int BatchSize; //build the offsets in parallel
+
+  int OffsetsType;
+  vtkDataArray *OffsetsArray; // container for offset array
+
+  // Construction
+  vtkBinTree(vtkIdType npts, vtkPoints *pts, int numLevels, int divs[3],
+             double bounds[6], int offsetsType) :
+    InPts(pts), NumPts(npts), NumLevels(numLevels), OffsetsType(offsetsType)
+    {
+      this->Divs[0] = divs[0];
+      this->Divs[1] = divs[1];
+      this->Divs[2] = divs[2];
+
+      this->Bounds[0] = bounds[0];
+      this->Bounds[1] = bounds[1];
+      this->Bounds[2] = bounds[2];
+      this->Bounds[3] = bounds[3];
+      this->Bounds[4] = bounds[4];
+      this->Bounds[5] = bounds[5];
+
+      // Build the levels. We create an extra one; it simplifies things later.
+      this->NumBins = 0;
+      for (int level=0; level < this->NumLevels; ++level)
+        {
+        this->Tree[level] = new UniformBinning(level, divs, bounds);
+        this->NumBins += this->Tree[level]->NumBins;
+        }
+      this->Tree[this->NumLevels] = new UniformBinning(this->NumLevels, divs, bounds);
+
+      this->BatchSize = 0;
+
+      this->OffsetsType = offsetsType;
+      this->OffsetsArray = NULL;
+    }
+
+  // Virtual functions supporting convenience methods in templated subclass.
+  virtual ~vtkBinTree()
+    {
+      for (int i=0; i <= this->NumLevels; ++i)
+        {
+        delete this->Tree[i];
+        }
+      if ( this->OffsetsArray )
+        {
+        this->OffsetsArray->Delete();
+        this->OffsetsArray = NULL;
+        }
+    }
+  virtual void Execute(vtkPointSet *input, vtkPolyData *output) = 0;
+  int GetNumberOfGlobalBins()
+    {
+      return this->NumBins;
+    }
+  int GetNumberOfBins(int level)
+    {
+      return this->Tree[level]->NumBins;
+    }
+  virtual vtkIdType GetLevelOffset(int level, vtkIdType& npts) = 0;
+  virtual vtkIdType GetBinOffset(int globalBin, vtkIdType& npts) = 0;
+  virtual vtkIdType GetLocalBinOffset(int level, int localBin, vtkIdType& npts) = 0;
+  // Sometimes the global bin needs to be expressed as a local bin number +
+  // tree level.
+  void TranslateGlobalBinToLocalBin(int globalBin, int& level, int& localBin)
+    {
+      for ( level=this->NumLevels-1;
+            globalBin < this->Tree[level]->LevelOffset; --level )
+        {
+        ;
+        }
+      localBin = globalBin - this->Tree[level]->LevelOffset;
+    }
+  void GetBinBounds(int globalBin, double bounds[6])
+    {
+      int level, localBin;
+      this->TranslateGlobalBinToLocalBin(globalBin, level, localBin);
+      return this->Tree[level]->GetBinBounds(localBin, bounds);
+    }
+  void GetLocalBinBounds(int level, int localBin, double bounds[6])
+    {
+      return this->Tree[level]->GetBinBounds(localBin, bounds);
+    }
+
+  void ExportMetaData(vtkPolyData *output)
+    {
+      this->OffsetsArray->SetName("BinOffsets");
+      output->GetFieldData()->AddArray(this->OffsetsArray);
+
+      // Bounding box
+      vtkDoubleArray *da = vtkDoubleArray::New();
+      da->SetName("BinBounds");
+      da->SetNumberOfTuples(6);
+      for (int i=0; i<6; ++i)
+        {
+        da->SetValue(i,this->Bounds[i]);
+        }
+      output->GetFieldData()->AddArray(da);
+      da->Delete();
+
+      // Divisions
+      vtkIntArray *ia = vtkIntArray::New();
+      ia->SetName("BinDivisions");
+      ia->SetNumberOfTuples(3);
+      for (int i=0; i<3; ++i)
+        {
+        ia->SetValue(i,this->Divs[i]);
+        }
+      output->GetFieldData()->AddArray(ia);
+      ia->Delete();
+
+    }
+};
+
+//----------------------------------------------------------------------------
+// Helper classes to support efficient computing, and threaded execution.
+namespace {
+
+//-----------------------------------------------------------------------------
+// The following tuple is what is sorted in the map. Note that it is templated
+// because depending on the number of points / bins to process we may want
+// to use vtkIdType. Otherwise for performance reasons it's best to use an int
+// (or other integral type). Typically sort() is 25-30% faster on smaller
+// integral types, plus it takes a heck less memory (when vtkIdType is 64-bit
+// and int is 32-bit).
+template <typename TTuple>
+class BinTuple
+{
+public:
+  TTuple PtId; //originating point id
+  TTuple Bin; //i-j-k index into bin space
+
+  //Operator< used to support the subsequent sort operation.
+  bool operator< (const BinTuple& tuple) const
+    {return Bin < tuple.Bin;}
+};
+
+//-----------------------------------------------------------------------------
+// This templated class manages the creation of the binning tree. It also
+// implements the operator() functors which are supplied to vtkSMPTools for
+// threaded processesing.
+template <typename TIds>
+struct BinTree : public vtkBinTree
+{
+  BinTuple<TIds> *Map; //the map to be sorted
+  TIds           *Offsets; //offsets for each bin into the map
+
+  // Construction
+  BinTree(vtkIdType npts, vtkPoints *pts, int numLevels, int divs[3],
+          double bounds[6], int offsetsType) :
+    vtkBinTree(npts, pts, numLevels, divs, bounds, offsetsType)
+    {
+      //one extra allocation to simplify traversal
+      this->Map = new BinTuple<TIds>[this->NumPts+1];
+      this->Map[this->NumPts].Bin = this->NumBins;
+      if ( offsetsType == VTK_INT )
+        {
+        this->OffsetsArray = vtkIntArray::New();
+        }
+      else
+        {
+        this->OffsetsArray = vtkIdTypeArray::New();
+        }
+      this->OffsetsArray->SetNumberOfTuples(this->NumBins+1);
+      this->Offsets = static_cast<TIds*>(this->OffsetsArray->GetVoidPointer(0));
+      this->Offsets[this->NumBins] = this->NumPts;
+    }
+
+  // Release allocated memory
+  virtual ~BinTree()
+    {
+      delete [] this->Map;
+      //Offsets data array deleted by superclass
+    }
+
+  // The number of point ids in a bin is determined by computing the
+  // difference between the offsets into the sorted points array.
+  vtkIdType GetNumberOfIds(vtkIdType binNum)
+    {
+      return (this->Offsets[binNum+1] - this->Offsets[binNum]);
+    }
+
+  // Given a bin number, return the point ids in that bin.
+  const BinTuple<TIds> *GetIds(vtkIdType binNum)
+    {
+      return this->Map + this->Offsets[binNum];
+    }
+
+  // Explicit point representation (e.g., vtkPointSet), faster path
+  template <typename T, typename TPts>
+  class MapPoints
+    {
+    public:
+      BinTree<T> *Tree;
+      const TPts *Points;
+      int Thresh[VTK_MAX_LEVEL];
+
+      MapPoints(BinTree<T> *tree, const TPts *pts) :
+        Tree(tree), Points(pts)
+        {
+          for (int i=0; i < this->Tree->NumLevels; ++i)
+            {
+            this->Thresh[i] = this->Tree->Tree[i]->LevelOffset;
+            }
+        }
+
+      void  operator()(vtkIdType ptId, vtkIdType end)
+        {
+        double p[3];
+        const TPts *x = this->Points + 3*ptId;
+        BinTuple<T> *t = this->Tree->Map + ptId;
+        int numLevels = this->Tree->NumLevels;
+        int level, idx, numBins = this->Tree->NumBins;
+        for ( ; ptId < end; ++ptId, x+=3, ++t )
+          {
+          t->PtId = ptId;
+          p[0] = static_cast<double>(x[0]);
+          p[1] = static_cast<double>(x[1]);
+          p[2] = static_cast<double>(x[2]);
+          idx = ptId % numBins;
+
+          for ( level=numLevels-1; idx < this->Thresh[level]; --level )
+            {
+            ;
+            }
+          t->Bin = this->Tree->Tree[level]->GetBinIndex(p);
+          }//for all points in this batch
+        }
+   };
+
+  // A clever way to build offsets in parallel. Basically each thread builds
+  // offsets across a range of the sorted map. Recall that offsets are an
+  // integral value referring to the locations of the sorted points that
+  // reside in each bin.
+  template <typename T>
+  class MapOffsets
+    {
+    public:
+      BinTree<T> *Tree;
+      vtkIdType NumPts;
+      int NumBins;
+      int BatchSize;
+
+      MapOffsets(BinTree<T> *tree, int numBatches) : Tree(tree)
+        {
+          this->NumPts = this->Tree->NumPts;
+          this->NumBins = this->Tree->NumBins;
+          this->BatchSize = ceil( static_cast<double>(this->NumPts) / numBatches);
+        }
+
+      // Traverse sorted points (i.e., tuples) and update bin offsets.
+      void  operator()(vtkIdType batch, vtkIdType batchEnd)
+        {
+        T *offsets = this->Tree->Offsets;
+        const BinTuple<T> *curPt =
+          this->Tree->Map + batch*this->BatchSize;
+        const BinTuple<T> *endBatchPt =
+          this->Tree->Map + batchEnd*this->BatchSize;
+        const BinTuple<T> *endPt =
+          this->Tree->Map + this->NumPts;
+        const BinTuple<T> *prevPt;
+        endBatchPt = ( endBatchPt > endPt ? endPt : endBatchPt );
+
+        // Special case at the very beginning of the mapped points array.  If
+        // the first point is in bin# N, then all bins up and including
+        // N must refer to the first point.
+        if ( curPt == this->Tree->Map )
+          {
+          prevPt = this->Tree->Map;
+          std::fill_n(offsets, curPt->Bin+1, 0); //point to the first points
+          }//at the very beginning of the map (sorted points array)
+
+        // We are entering this functor somewhere in the interior of the
+        // mapped points array. All we need to do is point to the entry
+        // position because we are interested only in prevPt->Bin.
+        else
+          {
+          prevPt = curPt;
+          }//else in the middle of a batch
+
+        // Okay we have a starting point for a bin run. Now we can begin
+        // filling in the offsets in this batch. A previous thread should
+        // have/will have completed the previous and subsequent runs outside
+        // of the [batch,batchEnd) range
+        for ( curPt=prevPt; curPt < endBatchPt; )
+          {
+          for ( ; curPt->Bin == prevPt->Bin && curPt <= endBatchPt;
+                ++curPt )
+            {
+            ; //advance
+            }
+          // Fill in any gaps in the offset array
+          std::fill_n(offsets + prevPt->Bin + 1,
+                      curPt->Bin - prevPt->Bin,
+                      curPt - this->Tree->Map);
+          prevPt = curPt;
+          }//for all batches in this range
+        }//operator()
+  };
+
+  //----------------------------------------------------------------------------
+  // Copy points to output
+  template <typename T, typename TPts>
+  struct ShufflePoints
+  {
+    BinTree<T> *Tree;
+    vtkIdType NumPts;
+    TPts *InPoints;
+    TPts *OutPoints;
+
+    ShufflePoints(BinTree<T> *tree, vtkIdType numPts, TPts *inPts, TPts *outPts) :
+      Tree(tree), NumPts(numPts), InPoints(inPts), OutPoints(outPts)
+      {
+      }
+
+    void operator() (vtkIdType ptId, vtkIdType endPtId)
+    {
+      BinTuple<TIds> *map = this->Tree->Map + ptId;
+      TPts *py = this->OutPoints + 3*ptId;
+      TPts *px;
+
+      for ( ; ptId < endPtId; ++ptId, ++map)
+        {
+        px = this->InPoints + 3*map->PtId;
+        *py++ = *px++;
+        *py++ = *px++;
+        *py++ = *px;
+        }
+    }
+  }; //ShufflePoints
+
+  //----------------------------------------------------------------------------
+  // Copy data arrays to output
+  template <typename T, typename TA>
+  struct ShuffleArray
+  {
+    BinTree<T> *Tree;
+    vtkIdType NumPts;
+    int NumComp;
+    TA *InArray;
+    TA *OutArray;
+
+    ShuffleArray(BinTree<T> *tree, vtkIdType numPts, int numComp, TA *in, TA *out) :
+      Tree(tree), NumPts(numPts), NumComp(numComp), InArray(in), OutArray(out)
+      {
+      }
+
+    void operator() (vtkIdType ptId, vtkIdType endPtId)
+    {
+      BinTuple<TIds> *map = this->Tree->Map + ptId;
+      TA *y = this->OutArray + this->NumComp*ptId;
+      TA *x;
+      int i;
+
+      for ( ; ptId < endPtId; ++ptId, ++map)
+        {
+        x = this->InArray + this->NumComp*map->PtId;
+        for (i=0; i<this->NumComp; ++i)
+          {
+          *y++ = *x++;
+          }
+        }
+    }
+
+    static void Execute(BinTree<TIds> *tree, vtkIdType numPts, int numComp,
+                        TA *in, TA *out)
+      {
+        ShuffleArray<TIds,TA> shuffle(tree,numPts,numComp,in,out);
+        vtkSMPTools::For(0,numPts, shuffle);
+      }
+
+  }; //ShuffleArray
+
+  // Bin the points, produce output
+  void Execute(vtkPointSet *input, vtkPolyData *output)
+    {
+      vtkPoints *inPts = input->GetPoints();
+      void *pts = inPts->GetVoidPointer(0);
+      vtkPoints *outPts = output->GetPoints();
+      int dataType = inPts->GetDataType();
+
+      if ( dataType == VTK_FLOAT )
+        {
+        MapPoints<TIds,float> mapper(this,static_cast<float*>(pts));
+        vtkSMPTools::For(0,this->NumPts, mapper);
+        }
+      else if ( dataType == VTK_DOUBLE )
+        {
+        MapPoints<TIds,double> mapper(this,static_cast<double*>(pts));
+        vtkSMPTools::For(0,this->NumPts, mapper);
+        }
+      else
+        {
+        vtkGenericWarningMacro("Type not supported\n");
+        return;
+        }
+
+      // Now gather the points into contiguous runs in bins
+      //
+      vtkSMPTools::Sort(this->Map, this->Map + this->NumPts);
+
+      // Build the offsets into the Map. The offsets are the positions of
+      // each bin into the sorted list. They mark the beginning of the
+      // list of points in each bin. Amazingly, this can be done in
+      // parallel.
+      //
+      int numBatches = static_cast<int>(
+        ceil(static_cast<double>(this->NumPts) / (5*this->NumBins)));
+      MapOffsets<TIds> offMapper(this,numBatches);
+      vtkSMPTools::For(0,numBatches, offMapper);
+
+      // Put the offset into the output for downstream filters
+      this->ExportMetaData(output);
+
+      // Shuffle the points around
+      if ( dataType == VTK_FLOAT )
+        {
+        ShufflePoints<TIds,float>
+          shuffle(this, this->NumPts, static_cast<float*>(inPts->GetVoidPointer(0)),
+                  static_cast<float*>(outPts->GetVoidPointer(0)));
+        vtkSMPTools::For(0,this->NumPts, shuffle);
+        }
+      else if ( dataType == VTK_DOUBLE )
+        {
+        ShufflePoints<TIds,double>
+          shuffle(this, this->NumPts, static_cast<double*>(inPts->GetVoidPointer(0)),
+                  static_cast<double*>(outPts->GetVoidPointer(0)));
+        vtkSMPTools::For(0,this->NumPts, shuffle);
+        }
+
+      // Now shuffle the data arrays
+      vtkPointData *inPD = input->GetPointData();
+      vtkPointData *outPD = output->GetPointData();
+      outPD->CopyAllocate(inPD,this->NumPts);
+
+      char *name;
+      vtkDataArray *iArray, *oArray;
+      void *iD, *oD;
+      int i, numComp, numArrays = inPD->GetNumberOfArrays();
+      for (i=0; i < numArrays; ++i)
+        {
+        iArray = inPD->GetArray(i);
+        if ( iArray )
+          {
+          name = iArray->GetName();
+          numComp = iArray->GetNumberOfComponents();
+          oArray = outPD->GetArray(name);
+          if ( !oArray )
+            {
+            continue;
+            }
+          oArray->SetNumberOfTuples(this->NumPts);
+          iD = iArray->GetVoidPointer(0);
+          oD = oArray->GetVoidPointer(0);
+          switch (iArray->GetDataType()) //template macro burps on multiple template parameters
+            {
+            case VTK_FLOAT:
+              ShuffleArray<TIds,float>::
+                Execute(this,this->NumPts,numComp,(float *)iD,(float *)oD); break;
+            case VTK_DOUBLE:
+              ShuffleArray<TIds,double>::
+                Execute(this,this->NumPts,numComp,(double *)iD,(double *)oD); break;
+            case VTK_INT:
+              ShuffleArray<TIds,int>::
+                Execute(this,this->NumPts,numComp,(int *)iD,(int *)oD); break;
+            case VTK_UNSIGNED_INT:
+              ShuffleArray<TIds,unsigned int>::
+                Execute(this,this->NumPts,numComp,(unsigned int *)iD,(unsigned int *)oD); break;
+            case VTK_CHAR:
+              ShuffleArray<TIds,char>::
+                Execute(this,this->NumPts,numComp,(char *)iD,(char *)oD); break;
+            case VTK_UNSIGNED_CHAR:
+              ShuffleArray<TIds,unsigned char>::
+                Execute(this,this->NumPts,numComp,(unsigned char *)iD,(unsigned char *)oD); break;
+            case VTK_SHORT:
+              ShuffleArray<TIds,short>::
+                Execute(this,this->NumPts,numComp,(short *)iD,(short *)oD); break;
+            case VTK_UNSIGNED_SHORT:
+              ShuffleArray<TIds,unsigned short>::
+                Execute(this,this->NumPts,numComp,(unsigned short *)iD,(unsigned short *)oD); break;
+            default:
+              vtkGenericWarningMacro("Unsupported attribute type");
+            }//over all VTK types
+          }//have valid array
+         }//for each candidate array
+    }
+
+  virtual vtkIdType GetLevelOffset(int level, vtkIdType& npts)
+  {
+    vtkIdType offset = this->Offsets[this->Tree[level]->LevelOffset];
+    vtkIdType offset2 = this->Offsets[this->Tree[level+1]->LevelOffset];
+
+    npts = offset2 - offset;
+    return offset;
+  }
+
+  virtual vtkIdType GetBinOffset(int globalBin, vtkIdType& npts)
+  {
+    vtkIdType offset = this->Offsets[globalBin];
+    vtkIdType offset2 = this->Offsets[globalBin+1];
+
+    npts = offset2 - offset;
+    return offset;
+  }
+
+  virtual vtkIdType GetLocalBinOffset(int level, int localBin, vtkIdType& npts)
+  {
+    vtkIdType offset = this->Offsets[this->Tree[level]->LevelOffset] + localBin;
+    vtkIdType offset2 = this->Offsets[this->Tree[level]->LevelOffset] + localBin + 1;
+
+    npts = offset2 - offset;
+    return offset;
+  }
+
+}; //BinTree
+
+
+} //anonymous namespace
+
+
+//================= Begin VTK class proper =======================================
+//----------------------------------------------------------------------------
+vtkHierarchicalBinningFilter::vtkHierarchicalBinningFilter()
+{
+
+  this->NumberOfLevels = 3;
+  this->Automatic = true;
+
+  this->Divisions[0] = this->Divisions[1] = this->Divisions[2] = 2;
+  this->Bounds[0] = this->Bounds[2] = this->Bounds[4] = 0.0;
+  this->Bounds[1] = this->Bounds[3] = this->Bounds[5] = 1.0;
+
+  this->Tree = NULL;
+}
+
+//----------------------------------------------------------------------------
+vtkHierarchicalBinningFilter::~vtkHierarchicalBinningFilter()
+{
+  if ( this->Tree )
+    {
+    delete this->Tree;
+    this->Tree = NULL;
+    }
+}
+
+//----------------------------------------------------------------------------
+// Produce the output data
+int vtkHierarchicalBinningFilter::RequestData(
+  vtkInformation *vtkNotUsed(request),
+  vtkInformationVector **inputVector,
+  vtkInformationVector *outputVector)
+{
+  // get the info objects
+  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
+  vtkInformation *outInfo = outputVector->GetInformationObject(0);
+
+  // get the input and output
+  vtkPointSet *input = vtkPointSet::SafeDownCast(
+    inInfo->Get(vtkDataObject::DATA_OBJECT()));
+  vtkPolyData *output = vtkPolyData::SafeDownCast(
+    outInfo->Get(vtkDataObject::DATA_OBJECT()));
+
+  // Check the input
+  if ( !input || !output )
+    {
+    return 1;
+    }
+  vtkIdType numPts = input->GetNumberOfPoints();
+  if ( numPts < 1 )
+    {
+    return 1;
+    }
+
+  // Set up the binning operation
+  vtkPoints *inPts = input->GetPoints();
+  int dataType = inPts->GetDataType();
+  vtkPoints *outPts = inPts->NewInstance();
+  outPts->SetDataType(dataType);
+  outPts->SetNumberOfPoints(numPts);
+  output->SetPoints(outPts);
+  outPts->UnRegister(this);
+
+  int numLevels = this->NumberOfLevels;
+  int *divs = this->Divisions;
+  double *bounds = this->Bounds;
+
+  // If automatic, try and create uniform-sized bins; cubes are ideal.
+  if ( this->Automatic )
+    {
+    inPts->GetBounds(this->Bounds);
+    double h[3];
+    h[0] = this->Bounds[1] - this->Bounds[0];
+    h[1] = this->Bounds[3] - this->Bounds[2];
+    h[2] = this->Bounds[5] - this->Bounds[4];
+    int min = (h[0] < h[1] ? (h[0] < h[2] ? 0 : 2) : (h[1] < h[2] ? 1 : 2));
+    divs[min] = ( h[min] > 0.0 ? 2 : 1);
+    h[min] = ( divs[min] == 1 ? 1.0 : h[min] );
+    for (int i=0; i<3; ++i)
+      {
+      if ( i != min )
+        {
+        divs[i]  = vtkMath::Round( divs[min]*h[i]/h[min] ) ;
+        divs[i] = ( divs[i] <= 0 ? 1 : divs[i] );
+        }
+      }
+    }
+
+  // Bin the points, produce output
+  if ( numPts >= VTK_INT_MAX )
+    {
+    this->Tree = new BinTree<vtkIdType>(numPts,inPts,numLevels,divs,bounds,VTK_ID_TYPE);
+    this->Tree->Execute(input,output);
+    }
+  else
+    {
+    this->Tree = new BinTree<int>(numPts,inPts,numLevels,divs,bounds,VTK_INT);
+    this->Tree->Execute(input,output);
+    }
+
+  return 1;
+}
+
+//----------------------------------------------------------------------------
+int vtkHierarchicalBinningFilter::
+GetNumberOfGlobalBins()
+{
+  if ( this->Tree )
+    {
+    return this->Tree->GetNumberOfGlobalBins();
+    }
+  else
+    {
+    return 0;
+    }
+}
+
+//----------------------------------------------------------------------------
+int vtkHierarchicalBinningFilter::
+GetNumberOfBins(int level)
+{
+  if ( this->Tree )
+    {
+    return this->Tree->GetNumberOfBins(level);
+    }
+  else
+    {
+    return 0;
+    }
+}
+
+//----------------------------------------------------------------------------
+vtkIdType vtkHierarchicalBinningFilter::
+GetLevelOffset(int level, vtkIdType& npts)
+{
+  if ( this->Tree )
+    {
+    return this->Tree->GetLevelOffset(level,npts);
+    }
+  else
+    {
+    return -1;
+    }
+}
+
+//----------------------------------------------------------------------------
+vtkIdType vtkHierarchicalBinningFilter::
+GetBinOffset(int globalBin, vtkIdType& npts)
+{
+  if ( this->Tree )
+    {
+    return this->Tree->GetBinOffset(globalBin,npts);
+    }
+  else
+    {
+    return -1;
+    }
+}
+
+//----------------------------------------------------------------------------
+vtkIdType vtkHierarchicalBinningFilter::
+GetLocalBinOffset(int level, int localBin, vtkIdType& npts)
+{
+  if ( this->Tree )
+    {
+    return this->Tree->GetLocalBinOffset(level,localBin,npts);
+    }
+  else
+    {
+    return -1;
+    }
+}
+
+//----------------------------------------------------------------------------
+void vtkHierarchicalBinningFilter::
+GetBinBounds(int globalBin, double bounds[6])
+{
+  if ( this->Tree )
+    {
+    return this->Tree->GetBinBounds(globalBin,bounds);
+    }
+  else
+    {
+    return;
+    }
+}
+
+//----------------------------------------------------------------------------
+void vtkHierarchicalBinningFilter::
+GetLocalBinBounds(int level, int localBin, double bounds[6])
+{
+  if ( this->Tree )
+    {
+    return this->Tree->GetLocalBinBounds(level,localBin,bounds);
+    }
+  else
+    {
+    return;
+    }
+}
+
+//----------------------------------------------------------------------------
+int vtkHierarchicalBinningFilter::
+FillInputPortInformation(int, vtkInformation *info)
+{
+  info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkPointSet");
+  return 1;
+}
+
+//----------------------------------------------------------------------------
+void vtkHierarchicalBinningFilter::PrintSelf(ostream& os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os,indent);
+
+  os << indent << "Number of Levels: "
+     << this->NumberOfLevels << endl;
+
+  os << indent << "Automatic: "
+     << (this->Automatic ? "On\n" : "Off\n");
+
+  for(int i=0;i<6;i++)
+    {
+    os << indent << "Bounds[" << i << "]: " << this->Bounds[i] << "\n";
+    }
+
+  os << indent << "Divisions: ("
+     << this->Divisions[0] << ","
+     << this->Divisions[1] << ","
+     << this->Divisions[2] << ")\n";
+}
diff --git a/Filters/Points/vtkHierarchicalBinningFilter.h b/Filters/Points/vtkHierarchicalBinningFilter.h
new file mode 100644
index 0000000000000000000000000000000000000000..fde84fa6446a403d6e6518f5453c8526a663de6e
--- /dev/null
+++ b/Filters/Points/vtkHierarchicalBinningFilter.h
@@ -0,0 +1,189 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkHierarchicalBinningFilter.h
+
+  Copyright (c) Kitware, Inc.
+  All rights reserved.
+  See LICENSE file 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.
+
+=========================================================================*/
+// .NAME vtkHierarchicalBinningFilter - uniform binning of points into
+// a hierarchical structure
+
+// .SECTION Description
+// vtkHierarchicalBinningFilter creates a spatial, hierarchical ordering of
+// input points. This hierarchy is suitable for level-of-detail rendering, or
+// multiresolution processing. Each level of the hierarchy is based on
+// uniform binning of space, where deeper levels (and its bins) are
+// repeatedly subdivided by a given branching factor. Points are associated
+// with bins at different levels, with the number of points in each level
+// proportional to the number of bins in that level. The output points are
+// sorted according to a bin number, where the bin number is unique,
+// monotonically increasing number representing the breadth first ordering of
+// all of the levels and their bins. Thus all points in a bin (or even a level)
+// are segmented into contiguous runs.
+//
+// Note that points are associated with different bins using a pseudo random
+// process. No points are repeated, and no new points are created, thus the
+// effect of executing this filter is simply to reorder the input points.
+//
+// The algorithm proceeds as follows: Given an initial bounding box, the
+// space is uniformally subdivided into bins of (M x N x O) dimensions; in
+// turn each subsequent level in the tree is further divided into (M x N x O)
+// bins (note that level 0 is a single, root bin). Thus the number of bins at
+// level L of the hierachical tree is: Nbins=(M^L x N^L x O^L). Once the
+// binning is created to a specified depth, then points are placed in the
+// bins using a pseudo-random sampling proportional to the number of bins in each
+// level. All input points are sorted in the order described above, with no
+// points repeated.
+//
+// The output of this filter are sorted points and associated point
+// attributes represented by a vtkPolyData. In addition, an offest integral
+// array is associated with the field data of the output, providing offsets
+// into the points list via a breadth-first traversal order. Metadata
+// describing the output is provided in the field data. Convenience functions
+// are also provided here to access the data in a particular bin or across a
+// level. (Using the offset array directly may result in higher performance.)
+//
+// While any vtkPointSet type can be provided as input, the output is
+// represented by an explicit representation of points via a
+// vtkPolyData. This output polydata will populate its instance of vtkPoints,
+// but no cells will be defined (i.e., no vtkVertex or vtkPolyVertex are
+// contained in the output).
+
+// .SECTION Caveats
+// This class has been threaded with vtkSMPTools. Using TBB or other
+// non-sequential type (set in the CMake variable
+// VTK_SMP_IMPLEMENTATION_TYPE) may improve performance significantly.
+
+// .SECTION See Also
+// vtkPointCloudFilter vtkQuadricClustering vtkStaticPointLocator
+
+#ifndef vtkHierarchicalBinningFilter_h
+#define vtkHierarchicalBinningFilter_h
+
+#include "vtkFiltersPointsModule.h" // For export macro
+#include "vtkPolyDataAlgorithm.h"
+
+#define VTK_MAX_LEVEL 12
+
+struct vtkBinTree;
+
+class VTKFILTERSPOINTS_EXPORT vtkHierarchicalBinningFilter : public vtkPolyDataAlgorithm
+{
+public:
+  // Description:
+  // Standard methods for instantiating, obtaining type information, and
+  // printing information.
+  static vtkHierarchicalBinningFilter *New();
+  vtkTypeMacro(vtkHierarchicalBinningFilter,vtkPolyDataAlgorithm);
+  void PrintSelf(ostream& os, vtkIndent indent);
+
+  // Description:
+  // Specify the number of levels in the spatial hierachy. By default, the
+  // number of levels is three.
+  vtkSetClampMacro(NumberOfLevels,int,1,VTK_MAX_LEVEL);
+  vtkGetMacro(NumberOfLevels,int);
+
+  // Description:
+  // Specify whether to determine the determine the level divisions, and the bounding
+  // box automatically (by default this is on). If off, then the user must specify both
+  // the bounding box and bin divisions. (Computing the bounding box can be slow for
+  // large point clouds, manual specification can save time.)
+  vtkSetMacro(Automatic,bool);
+  vtkGetMacro(Automatic,bool);
+  vtkBooleanMacro(Automatic,bool);
+
+  // Description:
+  // Set the number of branching divisions in each binning direction. Each
+  // level of the tree is subdivided by this factor. The Divisions[i] must be
+  // >= 1. Note: if Automatic subdivision is specified, the the Divisions are
+  // set by the filter.
+  vtkSetVector3Macro(Divisions,int);
+  vtkGetVectorMacro(Divisions,int,3);
+
+  // Description:
+  // Set the bounding box of the point cloud. If Automatic is enabled, then
+  // this is computed during filter execution. If manually specified
+  // (Automatic is off) then make sure the bounds is represented as
+  // (xmin,xmax, ymin,ymax, zmin,zmax). If the bounds specified is does not
+  // enclose the points, then points are clamped to lie in the bounding box.
+  vtkSetVector6Macro(Bounds,double);
+  vtkGetVectorMacro(Bounds,double,6);
+
+  // Description:
+  // Convenience methods for extracting useful information about this bin
+  // tree.  Return the number of total bins across all levels (i.e., the
+  // total global bins). Invoke this method after the bin tree has been
+  // built.
+  int GetNumberOfGlobalBins();
+
+  // Description:
+  // Convenience methods for extracting useful information about this bin
+  // tree.  Return the number of bins in a particular level of the
+  // tree. Invoke this method after the bin tree has been built.
+  int GetNumberOfBins(int level);
+
+  // Description:
+  // Convenience methods for extracting useful information about this bin
+  // tree.  Given a level, return the beginning point id and number of points
+  // that level. Invoke this method after the bin tree has been built.
+  vtkIdType GetLevelOffset(int level, vtkIdType& npts);
+
+  // Description:
+  // Convenience methods for extracting useful information about this bin
+  // tree.  Given a global bin number, return the point id and number of
+  // points for that bin. Invoke this method after the bin tree has been
+  // built.
+  vtkIdType GetBinOffset(int globalBin, vtkIdType& npts);
+
+  // Description:
+  // Convenience methods for extracting useful information about this bin
+  // tree.  Given a level, and the bin number in that level, return the
+  // offset point id and number of points for that bin. Invoke this method
+  // after the bin tree has been built.
+  vtkIdType GetLocalBinOffset(int level, int localBin, vtkIdType& npts);
+
+  // Description:
+  // Convenience methods for extracting useful information about a bin tree.
+  // Given a global bin number, return the bounds (xmin,xmax,ymin,ymax,zmin,zmax)
+  // for that bin. Invoke this method after the bin tree has been built.
+  void GetBinBounds(int globalBin, double bounds[6]);
+
+  // Description:
+  // Convenience methods for extracting useful information about a bin tree.
+  // Given a level, and a local bin number, return the bounds
+  // (xmin,xmax,ymin,ymax,zmin,zmax) for that bin. Invoke this method after
+  // the bin tree has been built.
+  void GetLocalBinBounds(int level, int localBin, double bounds[6]);
+
+protected:
+  vtkHierarchicalBinningFilter();
+  ~vtkHierarchicalBinningFilter();
+
+  // IVars
+  int NumberOfLevels;
+  bool Automatic;
+  int Divisions[3];
+  double Bounds[6];
+
+  // Handle to the underlying implementation. The representation is maintained so
+  // that the convenience functions can be invoked on the bin tree.
+  vtkBinTree *Tree;
+
+  virtual int RequestData(vtkInformation *, vtkInformationVector **,
+    vtkInformationVector *);
+  virtual int FillInputPortInformation(int port, vtkInformation *info);
+
+private:
+  vtkHierarchicalBinningFilter(const vtkHierarchicalBinningFilter&) VTK_DELETE_FUNCTION;
+  void operator=(const vtkHierarchicalBinningFilter&) VTK_DELETE_FUNCTION;
+
+};
+
+#endif
diff --git a/Filters/Points/vtkPCACurvatureEstimation.cxx b/Filters/Points/vtkPCACurvatureEstimation.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..1d23334e3a8b5194704d57a6344e148b54c55146
--- /dev/null
+++ b/Filters/Points/vtkPCACurvatureEstimation.cxx
@@ -0,0 +1,244 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkPCACurvatureEstimation.cxx
+
+  Copyright (c) Kitware, Inc.
+  All rights reserved.
+  See LICENSE file 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.
+
+=========================================================================*/
+#include "vtkPCACurvatureEstimation.h"
+
+#include "vtkObjectFactory.h"
+#include "vtkAbstractPointLocator.h"
+#include "vtkStaticPointLocator.h"
+#include "vtkPointSet.h"
+#include "vtkPoints.h"
+#include "vtkPointData.h"
+#include "vtkFloatArray.h"
+#include "vtkInformation.h"
+#include "vtkInformationVector.h"
+#include "vtkMath.h"
+#include "vtkSMPTools.h"
+#include "vtkSMPThreadLocalObject.h"
+
+vtkStandardNewMacro(vtkPCACurvatureEstimation);
+vtkCxxSetObjectMacro(vtkPCACurvatureEstimation,Locator,vtkAbstractPointLocator);
+
+
+namespace {
+
+//----------------------------------------------------------------------------
+// The threaded core of the algorithm.
+template <typename T>
+struct GenerateCurvature
+{
+  const T *Points;
+  vtkAbstractPointLocator *Locator;
+  int SampleSize;
+  float *Curvature;
+
+  // Don't want to allocate working arrays on every thread invocation. Thread local
+  // storage lots of new/delete.
+  vtkSMPThreadLocalObject<vtkIdList> PIds;
+
+  GenerateCurvature(T *points, vtkAbstractPointLocator *loc, int sample, float *curve) :
+    Points(points), Locator(loc), SampleSize(sample), Curvature(curve)
+    {
+    }
+
+  // Just allocate a little bit of memory to get started.
+  void Initialize()
+    {
+    vtkIdList*& pIds = this->PIds.Local();
+    pIds->Allocate(128); //allocate some memory
+    }
+
+  void operator() (vtkIdType ptId, vtkIdType endPtId)
+    {
+      const T *px = this->Points + 3*ptId;
+      const T *py;
+      float *c = this->Curvature + 3*ptId;
+      double x[3], mean[3], den;
+      vtkIdList*& pIds = this->PIds.Local();
+      vtkIdType numPts, nei;
+      int sample, i;
+      double *a[3], a0[3], a1[3], a2[3], xp[3];
+      a[0] = a0; a[1] = a1; a[2] = a2;
+      double *v[3], v0[3], v1[3], v2[3];
+      v[0] = v0; v[1] = v1; v[2] = v2;
+      double eVal[3];
+
+      for ( ; ptId < endPtId; ++ptId )
+        {
+        x[0] = static_cast<double>(*px++);
+        x[1] = static_cast<double>(*px++);
+        x[2] = static_cast<double>(*px++);
+
+        // Retrieve the local neighborhood
+        this->Locator->FindClosestNPoints(this->SampleSize, x, pIds);
+        numPts = pIds->GetNumberOfIds();
+
+        // First step: compute the mean position of the neighborhood.
+        mean[0] = mean[1] = mean[2] = 0.0;
+        for (sample=0; sample<numPts; ++sample)
+          {
+          nei = pIds->GetId(sample);
+          py = this->Points + 3*nei;
+          mean[0] += static_cast<double>(*py++);
+          mean[1] += static_cast<double>(*py++);
+          mean[2] += static_cast<double>(*py);
+          }
+        mean[0] /= static_cast<double>(numPts);
+        mean[1] /= static_cast<double>(numPts);
+        mean[2] /= static_cast<double>(numPts);
+
+        // Now compute the covariance matrix
+        a0[0] = a1[0] = a2[0] = 0.0;
+        a0[1] = a1[1] = a2[1] = 0.0;
+        a0[2] = a1[2] = a2[2] = 0.0;
+        for (sample=0; sample < numPts; ++sample )
+          {
+          nei = pIds->GetId(sample);
+          py = this->Points + 3*nei;
+          xp[0] = static_cast<double>(*py++) - mean[0];
+          xp[1] = static_cast<double>(*py++) - mean[1];
+          xp[2] = static_cast<double>(*py) - mean[2];
+          for (i=0; i < 3; i++)
+            {
+            a0[i] += xp[0] * xp[i];
+            a1[i] += xp[1] * xp[i];
+            a2[i] += xp[2] * xp[i];
+            }
+          }
+        for (i=0; i < 3; i++)
+          {
+          a0[i] /= static_cast<double>(numPts);
+          a1[i] /= static_cast<double>(numPts);
+          a2[i] /= static_cast<double>(numPts);
+          }
+
+        // Next extract the eigenvectors and values
+        vtkMath::Jacobi(a,eVal,v);
+
+        // Finally compute the curvatures
+        den = eVal[0] + eVal[1] + eVal[2];
+        *c++ = (eVal[0] - eVal[1]) / den;
+        *c++ = 2.0*(eVal[1] - eVal[2]) / den;
+        *c++ = 3.0*eVal[2] / den;
+
+        }//for all points
+    }
+
+  void Reduce()
+    {
+    }
+
+  static void Execute(vtkPCACurvatureEstimation *self, vtkIdType numPts, T *points,
+                      float *curvature)
+    {
+      GenerateCurvature gen(points, self->GetLocator(), self->GetSampleSize(),
+                            curvature);
+      vtkSMPTools::For(0, numPts, gen);
+    }
+}; //GenerateCurvature
+
+} //anonymous namespace
+
+
+//================= Begin VTK class proper =======================================
+//----------------------------------------------------------------------------
+vtkPCACurvatureEstimation::vtkPCACurvatureEstimation()
+{
+
+  this->SampleSize = 25;
+  this->Locator = vtkStaticPointLocator::New();
+}
+
+//----------------------------------------------------------------------------
+vtkPCACurvatureEstimation::~vtkPCACurvatureEstimation()
+{
+  this->SetLocator(NULL);
+}
+
+//----------------------------------------------------------------------------
+// Produce the output data
+int vtkPCACurvatureEstimation::RequestData(
+  vtkInformation *vtkNotUsed(request),
+  vtkInformationVector **inputVector,
+  vtkInformationVector *outputVector)
+{
+  // get the info objects
+  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
+  vtkInformation *outInfo = outputVector->GetInformationObject(0);
+
+  // get the input and output
+  vtkPointSet *input = vtkPointSet::SafeDownCast(
+    inInfo->Get(vtkDataObject::DATA_OBJECT()));
+  vtkPolyData *output = vtkPolyData::SafeDownCast(
+    outInfo->Get(vtkDataObject::DATA_OBJECT()));
+
+  // Check the input
+  if ( !input || !output )
+    {
+    return 1;
+    }
+  vtkIdType numPts = input->GetNumberOfPoints();
+  if ( numPts < 1 )
+    {
+    return 1;
+    }
+
+  // Start by building the locator.
+  if ( !this->Locator )
+    {
+    vtkErrorMacro(<<"Point locator required\n");
+    return 0;
+    }
+  this->Locator->SetDataSet(input);
+  this->Locator->BuildLocator();
+
+  // Generate the point curvature.
+  vtkFloatArray *curvature = vtkFloatArray::New();
+  curvature->SetNumberOfComponents(3);
+  curvature->SetNumberOfTuples(numPts);
+  curvature->SetName("PCACurvature");
+  float *c = static_cast<float*>(curvature->GetVoidPointer(0));
+
+  void *inPtr = input->GetPoints()->GetVoidPointer(0);
+  switch (input->GetPoints()->GetDataType())
+    {
+    vtkTemplateMacro(GenerateCurvature<VTK_TT>::
+                     Execute(this, numPts, (VTK_TT *)inPtr, c));
+    }
+
+  // Now send the curvatures to the output and clean up
+  output->SetPoints(input->GetPoints());
+  output->GetPointData()->PassData(input->GetPointData());
+  output->GetPointData()->AddArray(curvature);
+  curvature->Delete();
+
+  return 1;
+}
+
+//----------------------------------------------------------------------------
+int vtkPCACurvatureEstimation::
+FillInputPortInformation(int, vtkInformation *info)
+{
+  info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkPointSet");
+  return 1;
+}
+
+//----------------------------------------------------------------------------
+void vtkPCACurvatureEstimation::PrintSelf(ostream& os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os,indent);
+
+  os << indent << "Sample Size: " << this->SampleSize << "\n";
+
+}
diff --git a/Filters/Points/vtkPCACurvatureEstimation.h b/Filters/Points/vtkPCACurvatureEstimation.h
new file mode 100644
index 0000000000000000000000000000000000000000..beda00a77d3aa4b1edf6d8a73a0d0700524c7640
--- /dev/null
+++ b/Filters/Points/vtkPCACurvatureEstimation.h
@@ -0,0 +1,100 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkPCACurvatureEstimation.h
+
+  Copyright (c) Kitware, Inc.
+  All rights reserved.
+  See LICENSE file 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.
+
+=========================================================================*/
+// .NAME vtkPCACurvatureEstimation - generate curvature estimates using
+// principal component analysis
+
+// .SECTION Description
+// vtkPCACurvatureEstimation generates point normals using PCA (principal
+// component analysis).  Basically this estimates a local tangent plane
+// around sample point p by considering a small neighborhood of points
+// around p, and fitting a plane to the neighborhood (via PCA). A good
+// introductory reference is Hoppe's "Surface reconstruction from
+// unorganized points."
+//
+// To use this filter, sepcify a neighborhood size. This may have to be set
+// via experimentation. Optionally a point locator can be specified (instead
+// of the default locator), which is used to accelerate searches around a
+// sample point. Finally, the user should specify how to generate
+// consistently-oriented normals. As computed by PCA, normals may point in
+// +/- orientation, which may not be consistent with neighboring normals.
+//
+// The output of this filter is the same as the input except that a normal
+// per point is produced. (Note that these are unit normals.) While any
+// vtkPointSet type can be provided as input, the output is represented by an
+// explicit representation of points via a vtkPolyData. This output polydata
+// will populate its instance of vtkPoints, but no cells will be defined
+// (i.e., no vtkVertex or vtkPolyVertex are contained in the output).
+
+// .SECTION Caveats
+// This class has been threaded with vtkSMPTools. Using TBB or other
+// non-sequential type (set in the CMake variable
+// VTK_SMP_IMPLEMENTATION_TYPE) may improve performance significantly.
+
+// .SECTION See Also
+// vtkPCANormalEstimation
+
+#ifndef vtkPCACurvatureEstimation_h
+#define vtkPCACurvatureEstimation_h
+
+#include "vtkFiltersPointsModule.h" // For export macro
+#include "vtkPolyDataAlgorithm.h"
+
+class vtkAbstractPointLocator;
+
+
+class VTKFILTERSPOINTS_EXPORT vtkPCACurvatureEstimation : public vtkPolyDataAlgorithm
+{
+public:
+  // Description:
+  // Standard methods for instantiating, obtaining type information, and
+  // printing information.
+  static vtkPCACurvatureEstimation *New();
+  vtkTypeMacro(vtkPCACurvatureEstimation,vtkPolyDataAlgorithm);
+  void PrintSelf(ostream& os, vtkIndent indent);
+
+  // Description:
+  // For each sampled point, specify the number of the closest, surrounding
+  // points used to estimate the normal (the so called k-neighborhood). By
+  // default 25 points are used. Smaller numbers may speed performance at the
+  // cost of accuracy.
+  vtkSetClampMacro(SampleSize,int,1,VTK_INT_MAX);
+  vtkGetMacro(SampleSize,int);
+
+  // Description:
+  // Specify a point locator. By default a vtkStaticPointLocator is
+  // used. The locator performs efficient searches to locate points
+  // around a sample point.
+  void SetLocator(vtkAbstractPointLocator *locator);
+  vtkGetObjectMacro(Locator,vtkAbstractPointLocator);
+
+protected:
+  vtkPCACurvatureEstimation();
+  ~vtkPCACurvatureEstimation();
+
+  // IVars
+  int SampleSize;
+  vtkAbstractPointLocator *Locator;
+
+  virtual int RequestData(vtkInformation *, vtkInformationVector **,
+    vtkInformationVector *);
+  virtual int FillInputPortInformation(int port, vtkInformation *info);
+
+private:
+  vtkPCACurvatureEstimation(const vtkPCACurvatureEstimation&) VTK_DELETE_FUNCTION;
+  void operator=(const vtkPCACurvatureEstimation&) VTK_DELETE_FUNCTION;
+
+};
+
+#endif
diff --git a/Filters/Points/vtkPCANormalEstimation.cxx b/Filters/Points/vtkPCANormalEstimation.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..1e9d68797a9511d22a77e73a18e60f2bb43e1d2b
--- /dev/null
+++ b/Filters/Points/vtkPCANormalEstimation.cxx
@@ -0,0 +1,359 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkPCANormalEstimation.cxx
+
+  Copyright (c) Kitware, Inc.
+  All rights reserved.
+  See LICENSE file 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.
+
+=========================================================================*/
+#include "vtkPCANormalEstimation.h"
+
+#include "vtkObjectFactory.h"
+#include "vtkAbstractPointLocator.h"
+#include "vtkStaticPointLocator.h"
+#include "vtkPointSet.h"
+#include "vtkPoints.h"
+#include "vtkPointData.h"
+#include "vtkFloatArray.h"
+#include "vtkIdList.h"
+#include "vtkInformation.h"
+#include "vtkInformationVector.h"
+#include "vtkMath.h"
+#include "vtkSMPTools.h"
+#include "vtkSMPThreadLocalObject.h"
+
+vtkStandardNewMacro(vtkPCANormalEstimation);
+vtkCxxSetObjectMacro(vtkPCANormalEstimation,Locator,vtkAbstractPointLocator);
+
+
+namespace {
+
+//----------------------------------------------------------------------------
+// The threaded core of the algorithm.
+template <typename T>
+struct GenerateNormals
+{
+  const T *Points;
+  vtkAbstractPointLocator *Locator;
+  int SampleSize;
+  float *Normals;
+  int Orient;
+  double OPoint[3];
+  bool Flip;
+
+  // Don't want to allocate working arrays on every thread invocation. Thread local
+  // storage lots of new/delete.
+  vtkSMPThreadLocalObject<vtkIdList> PIds;
+
+  GenerateNormals(T *points, vtkAbstractPointLocator *loc, int sample, float *normals,
+                  int orient, double opoint[3], bool flip) :
+    Points(points), Locator(loc), SampleSize(sample), Normals(normals),
+    Orient(orient), Flip(flip)
+    {
+      this->OPoint[0] = opoint[0];
+      this->OPoint[1] = opoint[1];
+      this->OPoint[2] = opoint[2];
+    }
+
+  // Just allocate a little bit of memory to get started.
+  void Initialize()
+    {
+    vtkIdList*& pIds = this->PIds.Local();
+    pIds->Allocate(128); //allocate some memory
+    }
+
+  void operator() (vtkIdType ptId, vtkIdType endPtId)
+    {
+      const T *px = this->Points + 3*ptId;
+      const T *py;
+      float *n = this->Normals + 3*ptId;
+      double x[3], mean[3], o[3];
+      vtkIdList*& pIds = this->PIds.Local();
+      vtkIdType numPts, nei;
+      int sample, i;
+      double *a[3], a0[3], a1[3], a2[3], xp[3];
+      a[0] = a0; a[1] = a1; a[2] = a2;
+      double *v[3], v0[3], v1[3], v2[3];
+      v[0] = v0; v[1] = v1; v[2] = v2;
+      double eVecMin[3], eVal[3];
+      float flipVal = (this->Flip ? -1.0 : 1.0);
+
+      for ( ; ptId < endPtId; ++ptId )
+        {
+        x[0] = static_cast<double>(*px++);
+        x[1] = static_cast<double>(*px++);
+        x[2] = static_cast<double>(*px++);
+
+        // Retrieve the local neighborhood
+        this->Locator->FindClosestNPoints(this->SampleSize, x, pIds);
+        numPts = pIds->GetNumberOfIds();
+
+        // First step: compute the mean position of the neighborhood.
+        mean[0] = mean[1] = mean[2] = 0.0;
+        for (sample=0; sample<numPts; ++sample)
+          {
+          nei = pIds->GetId(sample);
+          py = this->Points + 3*nei;
+          mean[0] += static_cast<double>(*py++);
+          mean[1] += static_cast<double>(*py++);
+          mean[2] += static_cast<double>(*py);
+          }
+        mean[0] /= static_cast<double>(numPts);
+        mean[1] /= static_cast<double>(numPts);
+        mean[2] /= static_cast<double>(numPts);
+
+        // Now compute the covariance matrix
+        a0[0] = a1[0] = a2[0] = 0.0;
+        a0[1] = a1[1] = a2[1] = 0.0;
+        a0[2] = a1[2] = a2[2] = 0.0;
+        for (sample=0; sample < numPts; ++sample )
+          {
+          nei = pIds->GetId(sample);
+          py = this->Points + 3*nei;
+          xp[0] = static_cast<double>(*py++) - mean[0];
+          xp[1] = static_cast<double>(*py++) - mean[1];
+          xp[2] = static_cast<double>(*py) - mean[2];
+          for (i=0; i < 3; i++)
+            {
+            a0[i] += xp[0] * xp[i];
+            a1[i] += xp[1] * xp[i];
+            a2[i] += xp[2] * xp[i];
+            }
+          }
+        for (i=0; i < 3; i++)
+          {
+          a0[i] /= static_cast<double>(numPts);
+          a1[i] /= static_cast<double>(numPts);
+          a2[i] /= static_cast<double>(numPts);
+          }
+
+        // Next extract the eigenvectors and values
+        vtkMath::Jacobi(a,eVal,v);
+        //eVecMax[0] = v[0][0]; eVecMax[1] = v[1][0]; eVecMax[2] = v[2][0];
+        //eVecMid[0] = v[0][1]; eVecMid[1] = v[1][1]; eVecMid[2] = v[2][1];
+        eVecMin[0] = v[0][2]; eVecMin[1] = v[1][2]; eVecMin[2] = v[2][2];
+
+        // Orient properly
+        if ( this->Orient == vtkPCANormalEstimation::POINT )
+          {
+          o[0] = this->OPoint[0] - x[0];
+          o[1] = this->OPoint[1] - x[1];
+          o[2] = this->OPoint[2] - x[2];
+          if ( vtkMath::Dot(o,eVecMin) < 0.0 )
+            {
+            eVecMin[0] *= -1;
+            eVecMin[1] *= -1;
+            eVecMin[2] *= -1;
+            }
+          }
+
+        // Finally compute the point normal (which is the smallest eigenvector)
+        *n++ = flipVal * eVecMin[0];
+        *n++ = flipVal * eVecMin[1];
+        *n++ = flipVal * eVecMin[2];
+
+        }//for all points
+    }
+
+  void Reduce()
+    {
+    }
+
+  static void Execute(vtkPCANormalEstimation *self, vtkIdType numPts, T *points,
+                      float *normals, int orient, double opoint[3], bool flip)
+    {
+      GenerateNormals gen(points, self->GetLocator(), self->GetSampleSize(),
+                          normals, orient, opoint, flip);
+      vtkSMPTools::For(0, numPts, gen);
+    }
+}; //GenerateNormals
+
+} //anonymous namespace
+
+
+//================= Begin VTK class proper =======================================
+//----------------------------------------------------------------------------
+vtkPCANormalEstimation::vtkPCANormalEstimation()
+{
+
+  this->SampleSize = 25;
+  this->Locator = vtkStaticPointLocator::New();
+  this->NormalOrientation = vtkPCANormalEstimation::POINT;
+  this->OrientationPoint[0] = this->OrientationPoint[1] =
+    this->OrientationPoint[2] = 0.0;
+  this->FlipNormals = false;
+
+}
+
+//----------------------------------------------------------------------------
+vtkPCANormalEstimation::~vtkPCANormalEstimation()
+{
+  this->SetLocator(NULL);
+}
+
+//----------------------------------------------------------------------------
+// Produce the output data
+int vtkPCANormalEstimation::RequestData(
+  vtkInformation *vtkNotUsed(request),
+  vtkInformationVector **inputVector,
+  vtkInformationVector *outputVector)
+{
+  // get the info objects
+  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
+  vtkInformation *outInfo = outputVector->GetInformationObject(0);
+
+  // get the input and output
+  vtkPointSet *input = vtkPointSet::SafeDownCast(
+    inInfo->Get(vtkDataObject::DATA_OBJECT()));
+  vtkPolyData *output = vtkPolyData::SafeDownCast(
+    outInfo->Get(vtkDataObject::DATA_OBJECT()));
+
+  // Check the input
+  if ( !input || !output )
+    {
+    return 1;
+    }
+  vtkIdType numPts = input->GetNumberOfPoints();
+  if ( numPts < 1 )
+    {
+    return 1;
+    }
+
+  // Start by building the locator.
+  if ( !this->Locator )
+    {
+    vtkErrorMacro(<<"Point locator required\n");
+    return 0;
+    }
+  this->Locator->SetDataSet(input);
+  this->Locator->BuildLocator();
+
+  // Generate the point normals.
+  vtkFloatArray *normals = vtkFloatArray::New();
+  normals->SetNumberOfComponents(3);
+  normals->SetNumberOfTuples(numPts);
+  float *n = static_cast<float*>(normals->GetVoidPointer(0));
+
+  void *inPtr = input->GetPoints()->GetVoidPointer(0);
+  switch (input->GetPoints()->GetDataType())
+    {
+    vtkTemplateMacro(GenerateNormals<VTK_TT>::Execute(this, numPts, (VTK_TT *)inPtr, n,
+       this->NormalOrientation, this->OrientationPoint, this->FlipNormals));
+    }
+
+  // Orient the normals in a consistent fashion (if requested). This requires a traveral
+  // across the point cloud, traversing neighbors that are in close proximity.
+  if ( this->NormalOrientation == vtkPCANormalEstimation::GRAPH_TRAVERSAL )
+    {
+    vtkIdType ptId;
+    char *pointMap = new char [numPts];
+    std::fill_n(pointMap, numPts, static_cast<char>(0));
+    vtkIdList *wave = vtkIdList::New();
+    wave->Allocate(numPts/4+1,numPts);
+    vtkIdList *wave2 = vtkIdList::New();
+    wave2->Allocate(numPts/4+1,numPts);
+
+    for (ptId=0; ptId < numPts; ptId++)
+      {
+      if ( pointMap[ptId] == 0 )
+        {
+        wave->InsertNextId(ptId); //begin next connected wave
+        pointMap[ptId] = 1;
+        this->TraverseAndFlip (input->GetPoints(), n, pointMap, wave, wave2);
+        wave->Reset();
+        wave2->Reset();
+        }
+      }//for all points
+    delete [] pointMap;
+    wave->Delete();
+    wave2->Delete();
+    }//if graph traversal required
+
+  // Now send the normals to the output and clean up
+  output->SetPoints(input->GetPoints());
+  output->GetPointData()->PassData(input->GetPointData());
+  output->GetPointData()->SetNormals(normals);
+  normals->Delete();
+
+  return 1;
+}
+
+//----------------------------------------------------------------------------
+// Mark current point as visited and assign cluster number.  Note:
+// traversal occurs across proximally located points.
+//
+void vtkPCANormalEstimation::
+TraverseAndFlip (vtkPoints *inPts, float *normals, char *pointMap,
+                 vtkIdList *wave, vtkIdList *wave2)
+{
+  vtkIdType i, j, numPts, numIds, ptId;
+  vtkIdList *tmpWave;
+  double x[3];
+  float *n, *n2;
+  vtkIdList *neighborPointIds = vtkIdList::New();
+
+  while ( (numIds=wave->GetNumberOfIds()) > 0 )
+    {
+    for ( i=0; i < numIds; i++ ) //for all points in this wave
+      {
+      ptId = wave->GetId(i);
+      inPts->GetPoint(ptId,x);
+      n = normals + 3*ptId;
+      this->Locator->FindClosestNPoints(this->SampleSize,x,neighborPointIds);
+
+      numPts = neighborPointIds->GetNumberOfIds();
+      for (j=0; j < numPts; ++j)
+        {
+        ptId = neighborPointIds->GetId(j);
+        if ( pointMap[ptId] == 0 )
+          {
+          pointMap[ptId] = 1;
+          n2 = normals + 3*ptId;
+          if ( vtkMath::Dot(n,n2) < 0.0 )
+            {
+            *n2++ *= -1;
+            *n2++ *= -1;
+            *n2 *= -1;
+            }
+          wave2->InsertNextId(ptId);
+          }//if point not yet visited
+        }//for all neighbors
+      }//for all cells in this wave
+
+    tmpWave = wave;
+    wave = wave2;
+    wave2 = tmpWave;
+    tmpWave->Reset();
+    } //while wave is not empty
+
+  neighborPointIds->Delete();
+
+  return;
+}
+
+//----------------------------------------------------------------------------
+int vtkPCANormalEstimation::
+FillInputPortInformation(int, vtkInformation *info)
+{
+  info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkPointSet");
+  return 1;
+}
+
+//----------------------------------------------------------------------------
+void vtkPCANormalEstimation::PrintSelf(ostream& os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os,indent);
+
+  os << indent << "Sample Size: " << this->SampleSize << "\n";
+  os << indent << "Normal Orientation: " << this->NormalOrientation << endl;
+  os << indent << "Orientation Point: (" << this->OrientationPoint[0] << ","
+     << this->OrientationPoint[1] << "," << this->OrientationPoint[2] << ")\n";
+  os << indent << "Flip Normals: " << (this->FlipNormals ? "On\n" : "Off\n");
+
+}
diff --git a/Filters/Points/vtkPCANormalEstimation.h b/Filters/Points/vtkPCANormalEstimation.h
new file mode 100644
index 0000000000000000000000000000000000000000..62a3656c2e17fc28d3102615df94a0f8c025e405
--- /dev/null
+++ b/Filters/Points/vtkPCANormalEstimation.h
@@ -0,0 +1,156 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkPCANormalEstimation.h
+
+  Copyright (c) Kitware, Inc.
+  All rights reserved.
+  See LICENSE file 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.
+
+=========================================================================*/
+// .NAME vtkPCANormalEstimation - generate point normals using local tangent planes
+
+// .SECTION Description
+// vtkPCANormalEstimation generates point normals using PCA (principal
+// component analysis).  Basically this estimates a local tangent plane
+// around each sample point p by considering a small neighborhood of points
+// around p, and fitting a plane to the neighborhood (via PCA). A good
+// introductory reference is Hoppe's "Surface reconstruction from
+// unorganized points."
+//
+// To use this filter, specify a neighborhood size. This may have to be set
+// via experimentation. In addition, the user may optionally specify a point
+// locator (instead of the default locator), which is used to accelerate
+// searches around the sample point. Finally, the user should specify how to
+// generate consistently-oriented normals. As computed by PCA, normals may
+// point in arbitrary +/- orientation, which may not be consistent with
+// neighboring normals. There are three methods to address normal
+// consistency: 1) leave the normals as computed, 2) adjust the +/- sign of
+// the normals so that the normals all point towards a specified point, and
+// 3) perform a traversal of the point cloud and flip neighboring normals so
+// that they are mutually consistent.
+//
+// The output of this filter is the same as the input except that a normal
+// per point is produced. (Note that these are unit normals.) While any
+// vtkPointSet type can be provided as input, the output is represented by an
+// explicit representation of points via a vtkPolyData. This output polydata
+// will populate its instance of vtkPoints, but no cells will be defined
+// (i.e., no vtkVertex or vtkPolyVertex are contained in the output).
+
+// .SECTION Caveats
+// This class has been threaded with vtkSMPTools. Using TBB or other
+// non-sequential type (set in the CMake variable
+// VTK_SMP_IMPLEMENTATION_TYPE) may improve performance significantly.
+
+// .SECTION See Also
+// vtkPCACurvatureEstimation
+
+#ifndef vtkPCANormalEstimation_h
+#define vtkPCANormalEstimation_h
+
+#include "vtkFiltersPointsModule.h" // For export macro
+#include "vtkPolyDataAlgorithm.h"
+
+class vtkAbstractPointLocator;
+class vtkIdList;
+
+
+class VTKFILTERSPOINTS_EXPORT vtkPCANormalEstimation : public vtkPolyDataAlgorithm
+{
+public:
+  // Description:
+  // Standard methods for instantiating, obtaining type information, and
+  // printing information.
+  static vtkPCANormalEstimation *New();
+  vtkTypeMacro(vtkPCANormalEstimation,vtkPolyDataAlgorithm);
+  void PrintSelf(ostream& os, vtkIndent indent);
+
+  // Description:
+  // For each sampled point, specify the number of the closest, surrounding
+  // points used to estimate the normal (the so called k-neighborhood). By
+  // default 25 points are used. Smaller numbers may speed performance at the
+  // cost of accuracy.
+  vtkSetClampMacro(SampleSize,int,1,VTK_INT_MAX);
+  vtkGetMacro(SampleSize,int);
+
+  // Description:
+  // This enum is used to control how normals oriented is controlled.
+  enum Style
+  {
+    AS_COMPUTED=0,
+    POINT=1,
+    GRAPH_TRAVERSAL=3
+  };
+
+  // Description:
+  // Configure how the filter addresses consistency in normal
+  // oreientation. When initially computed using PCA, a point normal may
+  // point in the + or - direction, which may not be consistent with
+  // neighboring points. To address this, various strategies have been used
+  // to create consistent normals. The simplest approach is to do nothing
+  // (AsComputed). Another simple approach is to flip the normal based on its
+  // direction with respect to a specified point (i.e., point normals will
+  // point towrads the specified point). Finally, a full traversal of points
+  // across the graph of neighboring, connected points produces the best
+  // results but is computationally expensive.
+  vtkSetMacro(NormalOrientation,int);
+  vtkGetMacro(NormalOrientation,int);
+  void SetNormalOrientationToAsComputed()
+    { this->SetNormalOrientation(AS_COMPUTED); }
+  void SetNormalOrientationToPoint()
+    { this->SetNormalOrientation(POINT); }
+  void SetNormalOrientationToGraphTraversal()
+    { this->SetNormalOrientation(GRAPH_TRAVERSAL); }
+
+  // Description:
+  // If the normal orientation is to be consistent with a specified
+  // direction, then an orientation point should be set. The sign of the
+  // normals will be modified so that they point towards this point. By
+  // default, the specified orientation point is (0,0,0).
+  vtkSetVector3Macro(OrientationPoint,double);
+  vtkGetVectorMacro(OrientationPoint,double,3);
+
+  // Description:
+  // The normal orientation can be flipped by enabling this flag.
+  vtkSetMacro(FlipNormals,bool);
+  vtkGetMacro(FlipNormals,bool);
+  vtkBooleanMacro(FlipNormals,bool);
+
+  // Description:
+  // Specify a point locator. By default a vtkStaticPointLocator is
+  // used. The locator performs efficient searches to locate points
+  // around a sample point.
+  void SetLocator(vtkAbstractPointLocator *locator);
+  vtkGetObjectMacro(Locator,vtkAbstractPointLocator);
+
+protected:
+  vtkPCANormalEstimation();
+  ~vtkPCANormalEstimation();
+
+  // IVars
+  int SampleSize;
+  vtkAbstractPointLocator *Locator;
+  int NormalOrientation;
+  double OrientationPoint[3];
+  bool FlipNormals;
+
+  // Methods used to produce consistent normal orientations
+  void TraverseAndFlip (vtkPoints *inPts, float *normals, char *pointMap,
+                        vtkIdList *wave, vtkIdList *wave2);
+
+  // Pipeline management
+  virtual int RequestData(vtkInformation *, vtkInformationVector **,
+    vtkInformationVector *);
+  virtual int FillInputPortInformation(int port, vtkInformation *info);
+
+private:
+  vtkPCANormalEstimation(const vtkPCANormalEstimation&) VTK_DELETE_FUNCTION;
+  void operator=(const vtkPCANormalEstimation&) VTK_DELETE_FUNCTION;
+
+};
+
+#endif
diff --git a/Filters/Points/vtkPointCloudFilter.cxx b/Filters/Points/vtkPointCloudFilter.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..a3d2a5e7a3da9af2e9c8d7ced3b369775d6381ef
--- /dev/null
+++ b/Filters/Points/vtkPointCloudFilter.cxx
@@ -0,0 +1,325 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkPointCloudFilter.cxx
+
+  Copyright (c) Kitware, Inc.
+  All rights reserved.
+  See LICENSE file 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.
+
+=========================================================================*/
+#include "vtkPointCloudFilter.h"
+
+#include "vtkObjectFactory.h"
+#include "vtkAbstractPointLocator.h"
+#include "vtkStaticPointLocator.h"
+#include "vtkPointSet.h"
+#include "vtkDataArray.h"
+#include "vtkPoints.h"
+#include "vtkPointData.h"
+#include "vtkInformation.h"
+#include "vtkInformationVector.h"
+#include "vtkStreamingDemandDrivenPipeline.h"
+#include "vtkMath.h"
+#include "vtkSMPTools.h"
+#include "vtkSMPThreadLocalObject.h"
+#include "vtkArrayListTemplate.h" // For processing attribute data
+
+
+//----------------------------------------------------------------------------
+// Helper classes to support efficient computing, and threaded execution.
+namespace {
+
+//----------------------------------------------------------------------------
+// Map input points to output. Basically the third pass of the algorithm.
+template <typename T>
+struct MapPoints
+{
+  T *InPoints;
+  T *OutPoints;
+  const vtkIdType *PointMap;
+  ArrayList Arrays;
+
+  MapPoints(vtkIdType, T *inPts, vtkIdType numOutPts, T *outPts,
+            vtkIdType *map, vtkPointData *inPD, vtkPointData *outPD) :
+    InPoints(inPts), OutPoints(outPts), PointMap(map)
+    {
+      this->Arrays.AddArrays(numOutPts, inPD, outPD);
+    }
+
+  void operator() (vtkIdType ptId, vtkIdType endPtId)
+    {
+      T *inP, *outP;
+      const vtkIdType *map=this->PointMap;
+      vtkIdType outPtId;
+
+      for ( ; ptId < endPtId; ++ptId)
+        {
+        outPtId = map[ptId];
+        if ( outPtId != -1 )
+          {
+          inP = this->InPoints + 3*ptId;
+          outP = this->OutPoints + 3*outPtId;
+          *outP++ = *inP++;
+          *outP++ = *inP++;
+          *outP = *inP;
+          this->Arrays.Copy(ptId,outPtId);
+          }
+        }
+    }
+
+  static void Execute(vtkIdType numInPts, T *inPts,
+                      vtkIdType numOutPts, T *outPts, vtkIdType *map,
+                      vtkPointData *inPD, vtkPointData *outPD)
+    {
+      MapPoints copy(numInPts, inPts, numOutPts, outPts, map, inPD, outPD);
+      vtkSMPTools::For(0, numInPts, copy);
+    }
+
+}; //MapPoints
+
+//----------------------------------------------------------------------------
+// Map outlier points to second output. This is an optional pass of the
+// algorithm.
+template <typename T>
+struct MapOutliers
+{
+  T *InPoints;
+  T *OutPoints;
+  const vtkIdType *PointMap;
+  ArrayList Arrays;
+
+  MapOutliers(vtkIdType, T *inPts, vtkIdType numOutPts, T *outPts,
+              vtkIdType *map, vtkPointData *inPD, vtkPointData *outPD2) :
+    InPoints(inPts), OutPoints(outPts), PointMap(map)
+    {
+      this->Arrays.AddArrays(numOutPts, inPD, outPD2);
+    }
+
+  void operator() (vtkIdType ptId, vtkIdType endPtId)
+    {
+      T *inP, *outP;
+      const vtkIdType *map=this->PointMap;
+      vtkIdType outPtId;
+
+      for ( ; ptId < endPtId; ++ptId)
+        {
+        outPtId = map[ptId];
+        if ( outPtId < 0 )
+          {
+          outPtId = (-outPtId) - 1;
+          inP = this->InPoints + 3*ptId;
+          outP = this->OutPoints + 3*outPtId;
+          *outP++ = *inP++;
+          *outP++ = *inP++;
+          *outP = *inP;
+          this->Arrays.Copy(ptId,outPtId);
+          }
+        }
+    }
+
+  static void Execute(vtkIdType numInPts, T *inPts,
+                      vtkIdType numOutPts, T *outPts, vtkIdType *map,
+                      vtkPointData *inPD, vtkPointData *outPD2)
+    {
+      MapOutliers copy(numInPts, inPts, numOutPts, outPts, map, inPD, outPD2);
+      vtkSMPTools::For(0, numInPts, copy);
+    }
+
+}; //MapOutliers
+
+
+} //anonymous namespace
+
+//================= Begin class proper =======================================
+//----------------------------------------------------------------------------
+vtkPointCloudFilter::vtkPointCloudFilter()
+{
+  this->PointMap = NULL;
+  this->NumberOfPointsRemoved = 0;
+  this->GenerateOutliers = false;
+
+  // Optional second output of outliers
+  this->SetNumberOfOutputPorts(2);
+}
+
+//----------------------------------------------------------------------------
+vtkPointCloudFilter::~vtkPointCloudFilter()
+{
+  if ( this->PointMap )
+    {
+    delete [] this->PointMap;
+    }
+}
+
+//----------------------------------------------------------------------------
+const vtkIdType* vtkPointCloudFilter::GetPointMap()
+{
+  return this->PointMap;
+}
+
+//----------------------------------------------------------------------------
+vtkIdType vtkPointCloudFilter::GetNumberOfPointsRemoved()
+{
+  return this->NumberOfPointsRemoved;
+}
+
+//----------------------------------------------------------------------------
+// There are three high level passes. First we traverse all the input points
+// to see how many neighbors each point has within a specified radius, and a
+// map is created indicating whether an input point is to be copied to the
+// output. Next a prefix sum is used to count the output points, and to
+// update the mapping between the input and the output. Finally, non-removed
+// input points (and associated attributes) are copied to the output.
+int vtkPointCloudFilter::RequestData(
+  vtkInformation *vtkNotUsed(request),
+  vtkInformationVector **inputVector,
+  vtkInformationVector *outputVector)
+{
+  // get the info objects
+  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
+  vtkInformation *outInfo = outputVector->GetInformationObject(0);
+
+  // get the input and output
+  vtkPointSet *input = vtkPointSet::SafeDownCast(
+    inInfo->Get(vtkDataObject::DATA_OBJECT()));
+  vtkPolyData *output = vtkPolyData::SafeDownCast(
+    outInfo->Get(vtkDataObject::DATA_OBJECT()));
+
+  // Reset the filter
+  this->NumberOfPointsRemoved = 0;
+  if ( this->PointMap )
+    {
+    delete [] this->PointMap; //might have executed previously
+    }
+
+  // Check input
+  if ( !input || !output )
+    {
+    return 1;
+    }
+  vtkIdType numPts = input->GetNumberOfPoints();
+  if ( numPts < 1 )
+    {
+    return 1;
+    }
+
+  // Okay invoke filtering operation. This is always the initial pass.
+  this->PointMap = new vtkIdType[numPts];
+  if ( ! this->FilterPoints(input) )
+    {
+    return 1;
+    }
+
+  // Count the resulting points (prefix sum). The second pass of the algorithm; it
+  // could be threaded but prefix sum does not benefit very much from threading.
+  vtkIdType ptId;
+  vtkIdType count=0;
+  vtkIdType *map = this->PointMap;
+  for (ptId=0; ptId < numPts; ++ptId)
+    {
+    if ( map[ptId] != -1 )
+      {
+      map[ptId] = count;
+      count++;
+      }
+    }
+  this->NumberOfPointsRemoved = numPts - count;
+
+  // If the number of input and output points is the same we short circuit
+  // the process. Otherwise, copy the masked input points to the output.
+  vtkPointData *inPD = input->GetPointData();
+  vtkPointData *outPD = output->GetPointData();
+  if ( this->NumberOfPointsRemoved == 0 )
+    {
+    output->SetPoints(input->GetPoints());
+    outPD->PassData(inPD);
+    return 1;
+    }
+
+  // Okay copy the points from the input to the output. We use a threaded
+  // operation that provides a minor benefit (since it's mostly data
+  // movement with almost no computation).
+  outPD->CopyAllocate(inPD,count);
+  vtkPoints *points = input->GetPoints()->NewInstance();
+  points->SetDataType(input->GetPoints()->GetDataType());
+  points->SetNumberOfPoints(count);
+  output->SetPoints(points);
+
+  void *inPtr = input->GetPoints()->GetVoidPointer(0);
+  void *outPtr = output->GetPoints()->GetVoidPointer(0);
+  switch (output->GetPoints()->GetDataType())
+    {
+    vtkTemplateMacro(MapPoints<VTK_TT>::Execute(numPts, (VTK_TT *)inPtr, count,
+                              (VTK_TT *)outPtr, this->PointMap, inPD, outPD));
+    }
+
+  // Clean up. We leave the map in case the user wants to use it.
+  points->Delete();
+
+  // Create the second output if requested. Note that we are using a negative
+  // count in the map (offset by -1) which indicates the final position of
+  // the output point in the second output.
+  if ( this->GenerateOutliers && this->NumberOfPointsRemoved > 0 )
+    {
+    vtkInformation *outInfo2 = outputVector->GetInformationObject(1);
+    // get the second output
+    vtkPolyData *output2 = vtkPolyData::SafeDownCast(
+      outInfo2->Get(vtkDataObject::DATA_OBJECT()));
+    vtkPointData *outPD2 = output2->GetPointData();
+    outPD2->CopyAllocate(inPD,(count-1));
+
+    // Update map
+    count = 1; //offset by one
+    map = this->PointMap;
+    for (ptId=0; ptId < numPts; ++ptId)
+      {
+      if ( map[ptId] == -1 )
+        {
+        map[ptId] = (-count);
+        count++;
+        }
+    }
+
+    // Copy to second output
+    vtkPoints *points2 = input->GetPoints()->NewInstance();
+    points2->SetDataType(input->GetPoints()->GetDataType());
+    points2->SetNumberOfPoints(count-1);
+    output2->SetPoints(points2);
+    void *outPtr2 = output2->GetPoints()->GetVoidPointer(0);
+    switch (output->GetPoints()->GetDataType())
+      {
+      vtkTemplateMacro(MapOutliers<VTK_TT>::Execute(numPts, (VTK_TT *)inPtr, (count-1),
+                                  (VTK_TT *)outPtr2, this->PointMap, inPD, outPD2));
+      }
+    points2->Delete();
+    }
+
+  return 1;
+}
+
+//----------------------------------------------------------------------------
+int vtkPointCloudFilter::
+FillInputPortInformation(int, vtkInformation *info)
+{
+  info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkPointSet");
+  return 1;
+}
+
+
+//----------------------------------------------------------------------------
+void vtkPointCloudFilter::PrintSelf(ostream& os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os,indent);
+
+  os << indent << "Number of Points Removed: "
+     << this->NumberOfPointsRemoved << "\n";
+
+  os << indent << "Generate Outliers: "
+     << (this->GenerateOutliers ? "On\n" : "Off\n");
+
+}
diff --git a/Filters/Points/vtkPointCloudFilter.h b/Filters/Points/vtkPointCloudFilter.h
new file mode 100644
index 0000000000000000000000000000000000000000..951e9793867402c33c728e6530f9e8840bb25aa3
--- /dev/null
+++ b/Filters/Points/vtkPointCloudFilter.h
@@ -0,0 +1,118 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkPointCloudFilter.h
+
+  Copyright (c) Kitware, Inc.
+  All rights reserved.
+  See LICENSE file 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.
+
+=========================================================================*/
+// .NAME vtkPointCloudFilter - abstract class for filtering a point cloud
+
+// .SECTION Description
+// vtkPointCloudFilter serves as a base for classes that filter point clouds.
+// It takes as input any vtkPointSet (which represents points explicitly
+// using vtkPoints) and produces as output an explicit representation of
+// filtered points via a vtkPolyData. This output vtkPolyData will populate
+// its instance of vtkPoints, but no cells will be defined (i.e., no
+// vtkVertex or vtkPolyVertex are contained in the output). Also, after
+// filter execution, the user can request a vtkIdType* point map which
+// indicates how the input points were mapped to the output. A value of
+// PointMap[i] < 0 (where i is the ith input point) means that the ith input
+// point was removed. Otherwise PointMap[i] indicates the position in the
+// output vtkPoints array (point cloud).
+//
+// Optionally the filter may produce a second output. This second output is
+// another vtkPolyData with a vtkPoints that contains the points that were
+// removed during processing. To produce this second output, you must enable
+// GenerateOutliers. If this optional, second output is created, then the
+// contents of the PointMap are modified as well. In this case, a PointMap[i]
+// < 0 means that the ith input point has been mapped to the (-PointMap[i])-1
+// position in the second output's vtkPoints.
+
+// .SECTION Caveats
+// This class has been threaded with vtkSMPTools. Using TBB or other
+// non-sequential type (set in the CMake variable
+// VTK_SMP_IMPLEMENTATION_TYPE) may improve performance significantly.
+//
+// The filter copies point attributes from input to output consistent
+// with the filtering operation.
+//
+// It is convenient to use vtkPointGaussianMapper to render the points (since
+// this mapper does not require cells to be defined, and it is quite fast).
+
+// .SECTION See Also
+// vtkRadiusOutlierRemoval vtkPointGaussianMapper vtkThresholdPoints
+
+#ifndef vtkPointCloudFilter_h
+#define vtkPointCloudFilter_h
+
+#include "vtkFiltersPointsModule.h" // For export macro
+#include "vtkPolyDataAlgorithm.h"
+
+class vtkPointSet;
+
+
+class VTKFILTERSPOINTS_EXPORT vtkPointCloudFilter : public vtkPolyDataAlgorithm
+{
+public:
+  // Description:
+  // Standard methods to obtain type information, and print information.
+  vtkTypeMacro(vtkPointCloudFilter,vtkPolyDataAlgorithm);
+  void PrintSelf(ostream& os, vtkIndent indent);
+
+  // Description:
+  // Retrieve a map which indicates, on a point-by-point basis, where each
+  // input point was placed into the output. In other words, map[i] indicates
+  // where the ith input point is located in the output array of points. If
+  // map[i] < 0, then the ith input point was removed during filter
+  // execution.  This method returns valid information only after the filter
+  // executes.
+  const vtkIdType* GetPointMap();
+
+  // Description:
+  // Return the number of points removed after filter execution. The
+  // information retuned is valid only after the filter executes.
+  vtkIdType GetNumberOfPointsRemoved();
+
+  // Description:
+  // If this method is enabled (true), then a second output will be created
+  // that contains the outlier points. By default this is off (false).  Note
+  // that if enabled, the PointMap is modified as well: the outlier points
+  // are listed as well, with similar meaning, except their value is negated
+  // and shifted by -1.
+  vtkSetMacro(GenerateOutliers,bool);
+  vtkGetMacro(GenerateOutliers,bool);
+  vtkBooleanMacro(GenerateOutliers,bool);
+
+protected:
+  vtkPointCloudFilter();
+  ~vtkPointCloudFilter();
+
+  // All derived classes must implement this method. Note that a side effect of
+  // the class is to populate the PointMap. Zero is returned on error.
+  virtual int FilterPoints(vtkPointSet *input) = 0;
+
+  // Keep track of which points are removed through the point map
+  vtkIdType *PointMap;
+  vtkIdType NumberOfPointsRemoved;
+
+  // Does a second output need to be created?
+  bool GenerateOutliers;
+
+  virtual int RequestData(vtkInformation *, vtkInformationVector **,
+    vtkInformationVector *);
+  virtual int FillInputPortInformation(int port, vtkInformation *info);
+
+private:
+  vtkPointCloudFilter(const vtkPointCloudFilter&) VTK_DELETE_FUNCTION;
+  void operator=(const vtkPointCloudFilter&) VTK_DELETE_FUNCTION;
+
+};
+
+#endif
diff --git a/Filters/Points/vtkRadiusOutlierRemoval.cxx b/Filters/Points/vtkRadiusOutlierRemoval.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..9878457d2e2b4146075db1f37e7231e3b6b12fae
--- /dev/null
+++ b/Filters/Points/vtkRadiusOutlierRemoval.cxx
@@ -0,0 +1,152 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkRadiusOutlierRemoval.cxx
+
+  Copyright (c) Kitware, Inc.
+  All rights reserved.
+  See LICENSE file 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.
+
+=========================================================================*/
+#include "vtkRadiusOutlierRemoval.h"
+
+#include "vtkObjectFactory.h"
+#include "vtkAbstractPointLocator.h"
+#include "vtkStaticPointLocator.h"
+#include "vtkPointSet.h"
+#include "vtkPoints.h"
+#include "vtkIdList.h"
+#include "vtkSMPTools.h"
+#include "vtkSMPThreadLocalObject.h"
+
+
+vtkStandardNewMacro(vtkRadiusOutlierRemoval);
+vtkCxxSetObjectMacro(vtkRadiusOutlierRemoval,Locator,vtkAbstractPointLocator);
+
+//----------------------------------------------------------------------------
+// Helper classes to support efficient computing, and threaded execution.
+namespace {
+
+//----------------------------------------------------------------------------
+// The threaded core of the algorithm (first pass)
+template <typename T>
+struct RemoveOutliers
+{
+  const T *Points;
+  vtkAbstractPointLocator *Locator;
+  double Radius;
+  int NumNeighbors;
+  vtkIdType *PointMap;
+
+  // Don't want to allocate working arrays on every thread invocation. Thread local
+  // storage lots of new/delete.
+  vtkSMPThreadLocalObject<vtkIdList> PIds;
+
+  RemoveOutliers(T *points, vtkAbstractPointLocator *loc, double radius, int numNei,
+                 vtkIdType *map) : Points(points), Locator(loc), Radius(radius),
+                                   NumNeighbors(numNei), PointMap(map)
+    {
+    }
+
+  // Just allocate a little bit of memory to get started.
+  void Initialize()
+    {
+    vtkIdList*& pIds = this->PIds.Local();
+    pIds->Allocate(128); //allocate some memory
+    }
+
+  void operator() (vtkIdType ptId, vtkIdType endPtId)
+    {
+      const T *p = this->Points + 3*ptId;
+      vtkIdType *map = this->PointMap + ptId;
+      double x[3];
+      vtkIdList*& pIds = this->PIds.Local();
+
+      for ( ; ptId < endPtId; ++ptId)
+        {
+        x[0] = static_cast<double>(*p++);
+        x[1] = static_cast<double>(*p++);
+        x[2] = static_cast<double>(*p++);
+
+        this->Locator->FindPointsWithinRadius(this->Radius, x, pIds);
+        vtkIdType numPts = pIds->GetNumberOfIds();
+
+        // Keep in mind that The FindPoints method will always return at
+        // least one point (itself).
+        *map++ = ( numPts > this->NumNeighbors ? 1 : -1 );
+        }
+    }
+
+  void Reduce()
+    {
+    }
+
+  static void Execute(vtkRadiusOutlierRemoval *self, vtkIdType numPts,
+                      T *points, vtkIdType *map)
+    {
+      RemoveOutliers remove(points, self->GetLocator(), self->GetRadius(),
+                            self->GetNumberOfNeighbors(), map);
+      vtkSMPTools::For(0, numPts, remove);
+    }
+
+}; //RemoveOutliers
+
+} //anonymous namespace
+
+//================= Begin class proper =======================================
+//----------------------------------------------------------------------------
+vtkRadiusOutlierRemoval::vtkRadiusOutlierRemoval()
+{
+  this->Radius = 1.0;
+  this->NumberOfNeighbors = 2;
+  this->Locator = vtkStaticPointLocator::New();
+}
+
+//----------------------------------------------------------------------------
+vtkRadiusOutlierRemoval::~vtkRadiusOutlierRemoval()
+{
+  this->SetLocator(NULL);
+}
+
+//----------------------------------------------------------------------------
+// Traverse all the input points to see how many neighbors each point has
+// within a specified radius, and populate the map which indicates how points
+// are to be copied to the output.
+int vtkRadiusOutlierRemoval::FilterPoints(vtkPointSet *input)
+{
+  // Perform the point removal
+  // Start by building the locator
+  if ( !this->Locator )
+    {
+    vtkErrorMacro(<<"Point locator required\n");
+    return 0;
+    }
+  this->Locator->SetDataSet(input);
+  this->Locator->BuildLocator();
+
+  // Determine which points, if any, should be removed. We create a map
+  // to keep track. The bulk of the algorithmic work is done in this pass.
+  vtkIdType numPts = input->GetNumberOfPoints();
+  void *inPtr = input->GetPoints()->GetVoidPointer(0);
+  switch (input->GetPoints()->GetDataType())
+    {
+    vtkTemplateMacro(RemoveOutliers<VTK_TT>::
+                     Execute(this, numPts, (VTK_TT *)inPtr, this->PointMap));
+    }
+
+  return 1;
+}
+
+//----------------------------------------------------------------------------
+void vtkRadiusOutlierRemoval::PrintSelf(ostream& os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os,indent);
+
+  os << indent << "Radius: " << this->Radius << "\n";
+  os << indent << "Number of Neighbors: " << this->NumberOfNeighbors << "\n";
+  os << indent << "Locator: " << this->Locator << "\n";
+}
diff --git a/Filters/Points/vtkRadiusOutlierRemoval.h b/Filters/Points/vtkRadiusOutlierRemoval.h
new file mode 100644
index 0000000000000000000000000000000000000000..8a4de26a1225725799c4e96d7055a22600454ce6
--- /dev/null
+++ b/Filters/Points/vtkRadiusOutlierRemoval.h
@@ -0,0 +1,102 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkRadiusOutlierRemoval.h
+
+  Copyright (c) Kitware, Inc.
+  All rights reserved.
+  See LICENSE file 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.
+
+=========================================================================*/
+// .NAME vtkRadiusOutlierRemoval - remove isolated points
+
+// .SECTION Description
+// vtkRadiusOutlierRemoval removes isolated points; i.e., those points that
+// have few neighbors within a specified radius. The user must specify the
+// radius defining the local region, as well as the isolation threshold
+// (i.e., number of neighboring points required for the point to be
+// considered isolated). Optionally, users can specify a point locator to
+// accelerate local neighborhood search operations. (By default a
+// vtkStaticPointLocator will be created.)
+//
+// Note that while any vtkPointSet type can be provided as input, the output
+// is represented by an explicit representation of points via a
+// vtkPolyData. This output polydata will populate its instance of vtkPoints,
+// but no cells will be defined (i.e., no vtkVertex or vtkPolyVertex are
+// contained in the output). Also, after filter execution, the user can
+// request a vtkIdType* map which indicates how the input points were mapped
+// to the output. A value of map[i] (where i is the ith input point) less
+// than 0 means that the ith input point was removed. (See also the
+// superclass documentation for accessing the removed points through the
+// filter's second output.)
+
+// .SECTION Caveats
+// This class has been threaded with vtkSMPTools. Using TBB or other
+// non-sequential type (set in the CMake variable
+// VTK_SMP_IMPLEMENTATION_TYPE) may improve performance significantly.
+
+// .SECTION See Also
+// vtkPointCloudFilter vtkStatisticalOutlierRemoval vtkExtractPoints
+// vtkThresholdPoints vtkImplicitFunction
+
+#ifndef vtkRadiusOutlierRemoval_h
+#define vtkRadiusOutlierRemoval_h
+
+#include "vtkFiltersPointsModule.h" // For export macro
+#include "vtkPointCloudFilter.h"
+
+class vtkAbstractPointLocator;
+class vtkPointSet;
+
+
+class VTKFILTERSPOINTS_EXPORT vtkRadiusOutlierRemoval : public vtkPointCloudFilter
+{
+public:
+  // Description:
+  // Standard methods for instantiating, obtaining type information, and
+  // printing information.
+  static vtkRadiusOutlierRemoval *New();
+  vtkTypeMacro(vtkRadiusOutlierRemoval,vtkPointCloudFilter);
+  void PrintSelf(ostream& os, vtkIndent indent);
+
+  // Description:
+  // Specify the local search radius.
+  vtkSetClampMacro(Radius,double,0.0,VTK_FLOAT_MAX);
+  vtkGetMacro(Radius,double);
+
+  // Description:
+  // Specify the number of neighbors that a point must have, within
+  // the specified radius, for the point to not be considered isolated.
+  vtkSetClampMacro(NumberOfNeighbors,int,1,VTK_INT_MAX);
+  vtkGetMacro(NumberOfNeighbors,int);
+
+  // Description:
+  // Specify a point locator. By default a vtkStaticPointLocator is
+  // used. The locator performs efficient searches to locate near a
+  // specified interpolation position.
+  void SetLocator(vtkAbstractPointLocator *locator);
+  vtkGetObjectMacro(Locator,vtkAbstractPointLocator);
+
+protected:
+  vtkRadiusOutlierRemoval();
+  ~vtkRadiusOutlierRemoval();
+
+  double Radius;
+  int NumberOfNeighbors;
+  vtkAbstractPointLocator *Locator;
+
+  // All derived classes must implement this method. Note that a side effect of
+  // the class is to populate the PointMap. Zero is returned if there is a failure.
+  virtual int FilterPoints(vtkPointSet *input);
+
+private:
+  vtkRadiusOutlierRemoval(const vtkRadiusOutlierRemoval&) VTK_DELETE_FUNCTION;
+  void operator=(const vtkRadiusOutlierRemoval&) VTK_DELETE_FUNCTION;
+
+};
+
+#endif
diff --git a/Filters/Points/vtkSignedDistance.cxx b/Filters/Points/vtkSignedDistance.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..4d21f6975b50d8f0504f537acb40afaea68c56be
--- /dev/null
+++ b/Filters/Points/vtkSignedDistance.cxx
@@ -0,0 +1,466 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkSignedDistance.h
+
+  Copyright (c) Kitware, Inc.
+  All rights reserved.
+  See LICENSE file 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.
+
+=========================================================================*/
+#include "vtkSignedDistance.h"
+
+#include "vtkArrayListTemplate.h" // For processing attribute data
+#include "vtkImageData.h"
+#include "vtkInformation.h"
+#include "vtkInformationVector.h"
+#include "vtkMath.h"
+#include "vtkObjectFactory.h"
+#include "vtkPointData.h"
+#include "vtkPolyData.h"
+#include "vtkAbstractPointLocator.h"
+#include "vtkStaticPointLocator.h"
+#include "vtkStreamingDemandDrivenPipeline.h"
+#include "vtkDoubleArray.h"
+#include "vtkSMPTools.h"
+#include "vtkSMPThreadLocalObject.h"
+
+vtkStandardNewMacro(vtkSignedDistance);
+vtkCxxSetObjectMacro(vtkSignedDistance,Locator,vtkAbstractPointLocator);
+
+//----------------------------------------------------------------------------
+// Helper classes to support efficient computing, and threaded execution.
+namespace {
+
+// The threaded core of the algorithm
+template <typename T>
+struct SignedDistance
+{
+  T *Pts;
+  float *Normals;
+  int Dims[3];
+  double Origin[3];
+  double Spacing[3];
+  double Radius;
+  vtkAbstractPointLocator *Locator;
+  float *Scalars;
+
+  // Don't want to allocate these working arrays on every thread invocation,
+  // so make them thread local.
+  vtkSMPThreadLocalObject<vtkIdList> PIds;
+
+  SignedDistance(T *pts, float *normals, int dims[3], double origin[3], double spacing[3],
+                 double radius, vtkAbstractPointLocator *loc, float *scalars) :
+    Pts(pts), Normals(normals), Radius(radius), Locator(loc), Scalars(scalars)
+    {
+      for (int i=0; i < 3; ++i)
+        {
+        this->Dims[i] = dims[i];
+        this->Origin[i] = origin[i];
+        this->Spacing[i] = spacing[i];
+        }
+    }
+
+  // Just allocate a little bit of memory to get started.
+  void Initialize()
+    {
+    vtkIdList*& pIds = this->PIds.Local();
+    pIds->Allocate(128); //allocate some memory
+    }
+
+  // Threaded interpolation method
+  void operator() (vtkIdType slice, vtkIdType sliceEnd)
+    {
+      T *p;
+      float *n;
+      double x[3], dist;
+      vtkIdType numPts;
+      double *origin=this->Origin;
+      double *spacing=this->Spacing;
+      int ii, *dims=this->Dims;
+      vtkIdType ptId, jOffset, kOffset, sliceSize=dims[0]*dims[1];
+      vtkIdList*& pIds = this->PIds.Local();
+
+      for ( ; slice < sliceEnd; ++slice)
+        {
+        x[2] = origin[2] + slice*spacing[2];
+        kOffset = slice*sliceSize;
+
+        for ( int j=0;  j < dims[1]; ++j)
+          {
+          x[1] = origin[1] + j*spacing[1];
+          jOffset = j*dims[0];
+
+          for ( int i=0; i < dims[0]; ++i)
+            {
+            x[0] = origin[0] + i*spacing[0];
+            ptId = i + jOffset + kOffset;
+
+            // Compute signed distance from surrounding points
+            this->Locator->FindPointsWithinRadius(this->Radius, x, pIds);
+            numPts = pIds->GetNumberOfIds();
+            if ( numPts > 0 )
+              {
+              for (dist=0.0, ii=0; ii < numPts; ++ii)
+                {
+                p = this->Pts + 3*pIds->GetId(ii);
+                n = this->Normals + 3*pIds->GetId(ii);
+                dist += n[0]*(x[0]-p[0]) + n[1]*(x[1]-p[1]) + n[2]*(x[2]-p[2]);
+                }
+              this->Scalars[ptId] = dist / static_cast<double>(numPts);
+              }//if nearby points
+            }//over i
+          }//over j
+        }//over slices
+    }
+
+  void Reduce()
+    {
+    }
+
+  static void Execute(vtkSignedDistance *self, T *pts, float *normals, int dims[3],
+                      double origin[3], double spacing[3], float *scalars)
+    {
+      SignedDistance dist(pts, normals, dims, origin, spacing, self->GetRadius(),
+                          self->GetLocator(), scalars);
+      vtkSMPTools::For(0, dims[2], dist);
+    }
+
+}; //SignedDistance
+
+} //anonymous namespace
+
+//================= Begin class proper =======================================
+//----------------------------------------------------------------------------
+// Construct with sample dimensions=(256,256,256), and so that model bounds are
+// automatically computed from the input.
+vtkSignedDistance::vtkSignedDistance()
+{
+  this->Dimensions[0] = 256;
+  this->Dimensions[1] = 256;
+  this->Dimensions[2] = 256;
+
+  this->Bounds[0] = 0.0;
+  this->Bounds[1] = 0.0;
+  this->Bounds[2] = 0.0;
+  this->Bounds[3] = 0.0;
+  this->Bounds[4] = 0.0;
+  this->Bounds[5] = 0.0;
+
+  this->Radius = 0.1;
+
+  this->Locator = vtkStaticPointLocator::New();
+
+  this->Initialized = 0;
+}
+
+//----------------------------------------------------------------------------
+vtkSignedDistance::~vtkSignedDistance()
+{
+  this->SetLocator(NULL);
+}
+
+
+//----------------------------------------------------------------------------
+// Initialize the filter for appending data. You must invoke the
+// StartAppend() method before doing successive Appends(). It's also a
+// good idea to manually specify the model bounds; otherwise the input
+// bounds for the data will be used.
+void vtkSignedDistance::StartAppend()
+{
+  vtkInformation* outInfo = this->GetOutputInformation(0);
+  outInfo->Set(
+    vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT(),
+    vtkStreamingDemandDrivenPipeline::GetWholeExtent(outInfo),
+    6);
+
+  vtkDebugMacro(<< "Initializing data");
+  this->AllocateOutputData(this->GetOutput(), this->GetOutputInformation(0));
+  vtkIdType numPts = this->Dimensions[0] * this->Dimensions[1] * this->Dimensions[2];
+
+  // initialize output to initial unseen value at each location
+  float *newScalars = static_cast<float*>(
+    this->GetOutput()->GetPointData()->GetScalars()->GetVoidPointer(0));
+  std::fill_n(newScalars, numPts, this->Radius);
+
+  // Compute the initial bounds
+  double bounds[6];
+  vtkImageData *output=this->GetOutput();
+  double tempd[3];
+  int i;
+
+  // compute model bounds if not set previously
+  if ( this->Bounds[0] >= this->Bounds[1] ||
+       this->Bounds[2] >= this->Bounds[3] ||
+       this->Bounds[4] >= this->Bounds[5] )
+    {
+    vtkPolyData *input = vtkPolyData::SafeDownCast(this->GetInput());
+    input->GetBounds(bounds);
+    for (i=0; i<3; i++)
+      {
+      this->Bounds[2*i] = bounds[2*i];
+      this->Bounds[2*i+1] = bounds[2*i+1];
+      }
+    }
+
+  // Set volume origin and data spacing
+  output->SetOrigin(this->Bounds[0], this->Bounds[2], this->Bounds[4]);
+
+  for (i=0; i<3; i++)
+    {
+    tempd[i] = (this->Bounds[2*i+1] - this->Bounds[2*i]) /
+      (this->Dimensions[i] - 1);
+    }
+  output->SetSpacing(tempd);
+
+  outInfo->Set(vtkDataObject::ORIGIN(),this->Bounds[0],
+               this->Bounds[2], this->Bounds[4]);
+  outInfo->Set(vtkDataObject::SPACING(),tempd,3);
+
+  this->Initialized = 1;
+}
+
+
+//----------------------------------------------------------------------------
+// Append a data set to the existing output. To use this function,
+// you'll have to invoke the StartAppend() method before doing
+// successive appends. It's also a good idea to specify the model
+// bounds; otherwise the input model bounds is used. When you've
+// finished appending, use the EndAppend() method.
+void vtkSignedDistance::Append(vtkPolyData *input)
+{
+  vtkDebugMacro(<< "Appending data");
+
+  // There better be data
+  if ( !input || input->GetNumberOfPoints() < 1 )
+    {
+    return;
+    }
+
+  if ( !this->Initialized )
+    {
+    this->StartAppend();
+    }
+
+  // Make sure that there are normals and output scalars
+  vtkPoints *pts = input->GetPoints();
+  float *scalars = static_cast<float*>(
+    this->GetOutput()->GetPointData()->GetScalars()->GetVoidPointer(0));
+  vtkDataArray *normalArray = input->GetPointData()->GetNormals();
+  if ( ! normalArray || normalArray->GetDataType() != VTK_FLOAT )
+    {
+    vtkErrorMacro(<< "Float normals required!");
+    return;
+    }
+  float *normals = static_cast<float*>(normalArray->GetVoidPointer(0));
+
+  // Build the locator
+  if ( !this->Locator )
+    {
+    vtkErrorMacro(<<"Point locator required\n");
+    return;
+    }
+  this->Locator->SetDataSet(input);
+  this->Locator->BuildLocator();
+
+  // Finally: compute the signed distance function
+  vtkImageData *output=this->GetOutput();
+  void *inPtr = pts->GetVoidPointer(0);
+  switch (pts->GetDataType())
+    {
+    vtkTemplateMacro(SignedDistance<VTK_TT>::Execute(this, (VTK_TT *)inPtr, normals,
+             this->Dimensions, output->GetOrigin(), output->GetSpacing(), scalars));
+    }
+
+}
+
+//----------------------------------------------------------------------------
+// Method completes the append process (does the capping if requested).
+void vtkSignedDistance::EndAppend()
+{
+  vtkDataArray *newScalars;
+  vtkDebugMacro(<< "End append");
+
+  if (!(newScalars = this->GetOutput()->GetPointData()->GetScalars()))
+    {
+    vtkErrorMacro("No output produced.");
+    return;
+    }
+}
+
+//----------------------------------------------------------------------------
+int vtkSignedDistance::RequestInformation (
+  vtkInformation * vtkNotUsed(request),
+  vtkInformationVector ** vtkNotUsed( inputVector ),
+  vtkInformationVector *outputVector)
+{
+  // get the info objects
+  vtkInformation* outInfo = outputVector->GetInformationObject(0);
+
+  int i;
+  double ar[3], origin[3];
+
+  vtkDataObject::SetPointDataActiveScalarInfo(outInfo, VTK_FLOAT, 1);
+
+  outInfo->Set(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(),
+               0, this->Dimensions[0]-1,
+               0, this->Dimensions[1]-1,
+               0, this->Dimensions[2]-1);
+
+  for (i=0; i < 3; i++)
+    {
+    origin[i] = this->Bounds[2*i];
+    if ( this->Dimensions[i] <= 1 )
+      {
+      ar[i] = 1;
+      }
+    else
+      {
+      ar[i] = (this->Bounds[2*i+1] - this->Bounds[2*i])
+              / (this->Dimensions[i] - 1);
+      }
+    }
+  outInfo->Set(vtkDataObject::ORIGIN(),origin,3);
+  outInfo->Set(vtkDataObject::SPACING(),ar,3);
+
+  return 1;
+}
+
+//----------------------------------------------------------------------------
+int vtkSignedDistance::RequestData(
+  vtkInformation* vtkNotUsed( request ),
+  vtkInformationVector** inputVector,
+  vtkInformationVector* vtkNotUsed( outputVector ))
+{
+  // get the input
+  vtkInformation* inInfo = inputVector[0]->GetInformationObject(0);
+  vtkPolyData *input = vtkPolyData::SafeDownCast(
+    inInfo->Get(vtkDataObject::DATA_OBJECT()));
+
+  vtkDebugMacro(<< "Executing space carver");
+
+  if (input == NULL)
+    {
+    // we do not want to release the data because user might
+    // have called Append ...
+    return 0;
+    }
+
+  this->StartAppend();
+  this->Append(input);
+  this->EndAppend();
+
+  return 1;
+}
+
+//----------------------------------------------------------------------------
+// Set the i-j-k dimensions on which to sample the distance function.
+void vtkSignedDistance::SetDimensions(int i, int j, int k)
+{
+  int dim[3];
+
+  dim[0] = i;
+  dim[1] = j;
+  dim[2] = k;
+
+  this->SetDimensions(dim);
+}
+
+//----------------------------------------------------------------------------
+void vtkSignedDistance::SetDimensions(int dim[3])
+{
+  int dataDim, i;
+
+  vtkDebugMacro(<< " setting Dimensions to (" << dim[0] << "," << dim[1] << "," << dim[2] << ")");
+
+  if ( dim[0] != this->Dimensions[0] ||
+       dim[1] != this->Dimensions[1] ||
+       dim[2] != this->Dimensions[2] )
+    {
+    if ( dim[0]<1 || dim[1]<1 || dim[2]<1 )
+      {
+      vtkErrorMacro (<< "Bad Sample Dimensions, retaining previous values");
+      return;
+      }
+
+    for (dataDim=0, i=0; i<3 ; i++)
+      {
+      if (dim[i] > 1)
+        {
+        dataDim++;
+        }
+      }
+
+    if ( dataDim  < 3 )
+      {
+      vtkErrorMacro(<<"Sample dimensions must define a volume!");
+      return;
+      }
+
+    for ( i=0; i<3; i++)
+      {
+      this->Dimensions[i] = dim[i];
+      }
+
+    this->Modified();
+    }
+}
+
+//----------------------------------------------------------------------------
+int vtkSignedDistance::FillInputPortInformation(
+  int vtkNotUsed( port ), vtkInformation* info)
+{
+  info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkPolyData");
+  info->Set(vtkAlgorithm::INPUT_IS_OPTIONAL(), 1);
+  return 1;
+}
+
+//----------------------------------------------------------------------------
+int vtkSignedDistance::ProcessRequest(vtkInformation* request,
+                                        vtkInformationVector** inputVector,
+                                        vtkInformationVector* outputVector)
+{
+  // If we have no input then we will not generate the output because
+  // the user already called StartAppend/Append/EndAppend.
+  if(request->Has(vtkDemandDrivenPipeline::REQUEST_DATA_NOT_GENERATED()))
+    {
+    if(inputVector[0]->GetNumberOfInformationObjects() == 0)
+      {
+      vtkInformation* outInfo = outputVector->GetInformationObject(0);
+      outInfo->Set(vtkDemandDrivenPipeline::DATA_NOT_GENERATED(), 1);
+      }
+    return 1;
+    }
+  else if(request->Has(vtkDemandDrivenPipeline::REQUEST_DATA()))
+    {
+    if(inputVector[0]->GetNumberOfInformationObjects() == 0)
+      {
+      return 1;
+      }
+    }
+  return this->Superclass::ProcessRequest(request, inputVector, outputVector);
+}
+
+//----------------------------------------------------------------------------
+void vtkSignedDistance::PrintSelf(ostream& os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os,indent);
+
+  os << indent << "Radius: " << this->Radius << "\n";
+  os << indent << "Dimensions: (" << this->Dimensions[0] << ", "
+               << this->Dimensions[1] << ", "
+               << this->Dimensions[2] << ")\n";
+  os << indent << "Bounds: \n";
+  os << indent << "  Xmin,Xmax: (" << this->Bounds[0] << ", "
+     << this->Bounds[1] << ")\n";
+  os << indent << "  Ymin,Ymax: (" << this->Bounds[2] << ", "
+     << this->Bounds[3] << ")\n";
+  os << indent << "  Zmin,Zmax: (" << this->Bounds[4] << ", "
+     << this->Bounds[5] << ")\n";
+
+  os << indent << "Locator: " << this->Locator << "\n";
+}
diff --git a/Filters/Points/vtkSignedDistance.h b/Filters/Points/vtkSignedDistance.h
new file mode 100644
index 0000000000000000000000000000000000000000..dc293d11f7195f5ce3ad538a16b8b798cfab64aa
--- /dev/null
+++ b/Filters/Points/vtkSignedDistance.h
@@ -0,0 +1,156 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkSignedDistance.h
+
+  Copyright (c) Kitware, Inc.
+  All rights reserved.
+  See LICENSE file 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.
+
+=========================================================================*/
+// .NAME vtkSignedDistance - compute signed distances from an input point cloud
+// .SECTION Description
+// vtkSignedDistance is a filter that computes signed distances over a volume
+// from an input point cloud. The input point cloud must have point normals
+// defined, as well as an optional weighting function (e.g., probabilities
+// that the point measurements are accurate). Once the signed distance
+// function is computed, then the output volume may be isocontoured to
+// extract a approximating surface to the point cloud.
+//
+// To use this filter, specify the input vtkPolyData (which represents the
+// point cloud); define the sampling volume; specify a radius (which limits
+// the radius of influence of each point); and set an optional point locator
+// (to accelerate proximity operations, a vtkStaticPointLocator is used by
+// default). Note that large radius values may have significant impact on
+// performance. The volume is defined by specifying dimensions in the x-y-z
+// directions, as well as a domain bounds. By default the model bounds are
+// defined from the input points, but the user can also manually specify
+// them.
+//
+// This filter has one other unusual capability: it is possible to append
+// data in a sequence of operations to generate a single output. This is
+// useful when you have multiple point clouds (e.g., possibly from multiple
+// acqusition scans) and want to incrementally accumulate all the data.
+// However, the user must be careful to either specify the Bounds or
+// order the input such that the bounds of the first input completely
+// contains all other input data.  This is because the geometry and topology
+// of the output sampling volume cannot be changed after the initial Append
+// operation.
+//
+// This algorithm loosely follows the most excellent paper by Curless and
+// Levoy: "A Volumetric Method for Building Complex Models from Range
+// Images." As described in this paper it may produce a signed distance
+// volume that may contain the three data states for each voxel: near
+// surface, empty, or unseen (see vtkExtractSurface for additional
+// information). However, this algorithm has been extended to support
+// different interpolation kernels as follows.
+//
+// (Kernel description TODO including supplied weights.)
+//
+// .SECTION Caveats
+// This class has been threaded with vtkSMPTools. Using TBB or other
+// non-sequential type (set in the CMake variable
+// VTK_SMP_IMPLEMENTATION_TYPE) may improve performance significantly.
+
+// .SECTION See Also
+// vtkExtractSurface vtkImplicitModeller
+
+#ifndef vtkSignedDistance_h
+#define vtkSignedDistance_h
+
+#include "vtkFiltersPointsModule.h" // For export macro
+#include "vtkImageAlgorithm.h"
+
+class vtkPolyData;
+class vtkAbstractPointLocator;
+
+
+class VTKFILTERSPOINTS_EXPORT vtkSignedDistance : public vtkImageAlgorithm
+{
+public:
+  // Description:
+  // Standard methods for instantiating the class, providing type information,
+  // and printing.
+  static vtkSignedDistance *New();
+  vtkTypeMacro(vtkSignedDistance,vtkImageAlgorithm);
+  void PrintSelf(ostream& os, vtkIndent indent);
+
+  // Description:
+  // Set/Get the i-j-k dimensions on which to computer the distance function.
+  vtkGetVectorMacro(Dimensions,int,3);
+  void SetDimensions(int i, int j, int k);
+  void SetDimensions(int dim[3]);
+
+  // Description:
+  // Set / get the region in space in which to perform the sampling. If
+  // not specified, it will be computed automatically.
+  vtkSetVector6Macro(Bounds,double);
+  vtkGetVectorMacro(Bounds,double,6);
+
+  // Description:
+  // Set / get the radius of influence of each point. Smaller values
+  // generally improve performance markedly.
+  vtkSetClampMacro(Radius,double,0.0,VTK_FLOAT_MAX);
+  vtkGetMacro(Radius,double);
+
+  // Description:
+  // Specify a point locator. By default a vtkStaticPointLocator is
+  // used. The locator performs efficient searches to locate points
+  // surrounding a voxel (within the specified radius).
+  void SetLocator(vtkAbstractPointLocator *locator);
+  vtkGetObjectMacro(Locator,vtkAbstractPointLocator);
+
+  // Description:
+  // Initialize the filter for appending data. You must invoke the
+  // StartAppend() method before doing successive Appends(). It's also a
+  // good idea to manually specify the model bounds; otherwise the input
+  // bounds for the data will be used.
+  void StartAppend();
+
+  // Description:
+  // Append a data set to the existing output. To use this function,
+  // you'll have to invoke the StartAppend() method before doing
+  // successive appends. It's also a good idea to specify the model
+  // bounds; otherwise the input model bounds is used. When you've
+  // finished appending, use the EndAppend() method.
+  void Append(vtkPolyData *input);
+
+  // Description:
+  // Method completes the append process.
+  void EndAppend();
+
+  // See the vtkAlgorithm for a desciption of what these do
+  int ProcessRequest(vtkInformation*,
+                     vtkInformationVector**,
+                     vtkInformationVector*);
+
+protected:
+  vtkSignedDistance();
+  ~vtkSignedDistance();
+
+  int Dimensions[3];
+  double Bounds[6];
+  double Radius;
+  vtkAbstractPointLocator *Locator;
+
+  // Flag tracks whether process needs initialization
+  int Initialized;
+
+  virtual int RequestInformation (vtkInformation *,
+                                  vtkInformationVector **,
+                                  vtkInformationVector *);
+  virtual int RequestData (vtkInformation *,
+                           vtkInformationVector **, vtkInformationVector *);
+  virtual int FillInputPortInformation(int, vtkInformation*);
+
+private:
+  vtkSignedDistance(const vtkSignedDistance&) VTK_DELETE_FUNCTION;
+  void operator=(const vtkSignedDistance&) VTK_DELETE_FUNCTION;
+
+};
+
+#endif
diff --git a/Filters/Points/vtkStatisticalOutlierRemoval.cxx b/Filters/Points/vtkStatisticalOutlierRemoval.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..02a90ab7e622f41a69f18a77518985557d73ed83
--- /dev/null
+++ b/Filters/Points/vtkStatisticalOutlierRemoval.cxx
@@ -0,0 +1,347 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkStatisticalOutlierRemoval.cxx
+
+  Copyright (c) Kitware, Inc.
+  All rights reserved.
+  See LICENSE file 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.
+
+=========================================================================*/
+#include "vtkStatisticalOutlierRemoval.h"
+
+#include "vtkObjectFactory.h"
+#include "vtkAbstractPointLocator.h"
+#include "vtkStaticPointLocator.h"
+#include "vtkPointSet.h"
+#include "vtkPoints.h"
+#include "vtkIdList.h"
+#include "vtkSMPTools.h"
+#include "vtkSMPThreadLocalObject.h"
+#include "vtkMath.h"
+
+vtkStandardNewMacro(vtkStatisticalOutlierRemoval);
+vtkCxxSetObjectMacro(vtkStatisticalOutlierRemoval,Locator,vtkAbstractPointLocator);
+
+//----------------------------------------------------------------------------
+// Helper classes to support efficient computing, and threaded execution.
+namespace {
+
+//----------------------------------------------------------------------------
+// The threaded core of the algorithm (first pass)
+template <typename T>
+struct ComputeMeanDistance
+{
+  const T *Points;
+  vtkAbstractPointLocator *Locator;
+  int SampleSize;
+  float *Distance;
+  double Mean;
+
+  // Don't want to allocate working arrays on every thread invocation. Thread local
+  // storage lots of new/delete.
+  vtkSMPThreadLocalObject<vtkIdList> PIds;
+  vtkSMPThreadLocal<double> ThreadMean;
+  vtkSMPThreadLocal<vtkIdType> ThreadCount;
+
+  ComputeMeanDistance(T *points, vtkAbstractPointLocator *loc, int size, float *d) :
+    Points(points), Locator(loc), SampleSize(size), Distance(d), Mean(0.0)
+    {
+    }
+
+  // Just allocate a little bit of memory to get started.
+  void Initialize()
+    {
+    vtkIdList*& pIds = this->PIds.Local();
+    pIds->Allocate(128); //allocate some memory
+
+    double &threadMean = this->ThreadMean.Local();
+    threadMean = 0.0;
+
+    vtkIdType &threadCount = this->ThreadCount.Local();
+    threadCount = 0;
+    }
+
+  // Compute average distance for each point, plus accumlate summation of
+  // mean distances and count (for averaging in the Reduce() method).
+  void operator() (vtkIdType ptId, vtkIdType endPtId)
+    {
+      const T *px = this->Points + 3*ptId;
+      const T *py;
+      double x[3], y[3];
+      vtkIdList*& pIds = this->PIds.Local();
+      double &threadMean = this->ThreadMean.Local();
+      vtkIdType &threadCount = this->ThreadCount.Local();
+
+      for ( ; ptId < endPtId; ++ptId)
+        {
+        x[0] = static_cast<double>(*px++);
+        x[1] = static_cast<double>(*px++);
+        x[2] = static_cast<double>(*px++);
+
+        // The method FindClosestNPoints will include the current point, so
+        // we increase the sample size by one.
+        this->Locator->FindClosestNPoints(this->SampleSize+1, x, pIds);
+        vtkIdType numPts = pIds->GetNumberOfIds();
+
+        double sum = 0.0;
+        vtkIdType nei;
+        for (int sample=0; sample < numPts; ++sample)
+          {
+          nei = pIds->GetId(sample);
+          if ( nei != ptId ) //exclude ourselves
+            {
+            py = this->Points + 3*nei;
+            y[0] = static_cast<double>(*py++);
+            y[1] = static_cast<double>(*py++);
+            y[2] = static_cast<double>(*py);
+            sum += sqrt( vtkMath::Distance2BetweenPoints(x,y) );
+            }
+          }//sum the lengths of all samples exclusing current point
+
+        // Average the lengths; again exclude ourselves
+        if ( numPts > 0 )
+          {
+          this->Distance[ptId] = sum / static_cast<double>(numPts-1);
+          threadMean += this->Distance[ptId];
+          threadCount++;
+          }
+        else //ignore if no points are found, something bad has happened
+          {
+          this->Distance[ptId] = VTK_FLOAT_MAX; //the effect is to eliminate it
+          }
+        }
+    }
+
+  // Compute the mean by compositing all threads
+  void Reduce()
+    {
+      double mean=0.0;
+      vtkIdType count=0;
+
+      vtkSMPThreadLocal<double>::iterator mItr;
+      vtkSMPThreadLocal<double>::iterator mEnd = this->ThreadMean.end();
+      for ( mItr=this->ThreadMean.begin(); mItr != mEnd; ++mItr )
+        {
+        mean += *mItr;
+        }
+
+      vtkSMPThreadLocal<vtkIdType>::iterator cItr;
+      vtkSMPThreadLocal<vtkIdType>::iterator cEnd = this->ThreadCount.end();
+      for ( cItr=this->ThreadCount.begin(); cItr != cEnd; ++cItr )
+        {
+        count += *cItr;
+        }
+
+      this->Mean = mean / static_cast<double>(count);
+    }
+
+  static void Execute(vtkStatisticalOutlierRemoval *self, vtkIdType numPts,
+                      T *points, float *distances, double& mean)
+    {
+      ComputeMeanDistance compute(points, self->GetLocator(),
+                                  self->GetSampleSize(), distances);
+      vtkSMPTools::For(0, numPts, compute);
+      mean = compute.Mean;
+    }
+
+}; //ComputeMeanDistance
+
+//----------------------------------------------------------------------------
+// Now that the mean is known, compute the standard deviation
+struct ComputeStdDev
+{
+  float *Distances;
+  double Mean;
+  double StdDev;
+  vtkSMPThreadLocal<double> ThreadSigma;
+  vtkSMPThreadLocal<vtkIdType> ThreadCount;
+
+  ComputeStdDev(float *d, double mean) : Distances(d), Mean(mean), StdDev(0.0)
+    {
+    }
+
+  void Initialize()
+    {
+    double &threadSigma = this->ThreadSigma.Local();
+    threadSigma = 0.0;
+
+    vtkIdType &threadCount = this->ThreadCount.Local();
+    threadCount = 0;
+    }
+
+  void operator() (vtkIdType ptId, vtkIdType endPtId)
+    {
+      double &threadSigma = this->ThreadSigma.Local();
+      vtkIdType &threadCount = this->ThreadCount.Local();
+      float d;
+
+      for ( ; ptId < endPtId; ++ptId)
+        {
+        d = this->Distances[ptId];
+        if ( d < VTK_FLOAT_MAX )
+          {
+          threadSigma += (this->Mean - d) * (this->Mean - d);
+          threadCount++;
+          }
+        else
+          {
+          continue; //skip bad point
+          }
+        }
+    }
+
+  void Reduce()
+    {
+      double sigma=0.0;
+      vtkIdType count=0;
+
+      vtkSMPThreadLocal<double>::iterator sItr;
+      vtkSMPThreadLocal<double>::iterator sEnd = this->ThreadSigma.end();
+      for ( sItr=this->ThreadSigma.begin(); sItr != sEnd; ++sItr )
+        {
+        sigma += *sItr;
+        }
+
+      vtkSMPThreadLocal<vtkIdType>::iterator cItr;
+      vtkSMPThreadLocal<vtkIdType>::iterator cEnd = this->ThreadCount.end();
+      for ( cItr=this->ThreadCount.begin(); cItr != cEnd; ++cItr )
+        {
+        count += *cItr;
+        }
+
+      this->StdDev = sqrt( sigma / static_cast<double>(count) );
+    }
+
+  static void Execute(vtkIdType numPts, float *distances,
+                      double mean, double& sigma)
+    {
+      ComputeStdDev stdDev(distances, mean);
+      vtkSMPTools::For(0, numPts, stdDev);
+      sigma = stdDev.StdDev;
+    }
+
+}; //ComputeStdDev
+
+//----------------------------------------------------------------------------
+// Statistics are computed, now filter the points
+struct RemoveOutliers
+{
+  double Mean;
+  double Sigma;
+  float *Distances;
+  vtkIdType *PointMap;
+
+  RemoveOutliers(double mean, double sigma, float *distances, vtkIdType *map) :
+    Mean(mean), Sigma(sigma), Distances(distances), PointMap(map)
+    {
+    }
+
+  void operator() (vtkIdType ptId, vtkIdType endPtId)
+    {
+      vtkIdType *map = this->PointMap + ptId;
+      float *d = this->Distances + ptId;
+      double mean=this->Mean, sigma=this->Sigma;
+
+      for ( ; ptId < endPtId; ++ptId)
+        {
+        *map++ = ( fabs(*d++ - mean) <= sigma ? 1 : -1 );
+        }
+    }
+
+  static void Execute(vtkIdType numPts, float *distances, double mean,
+                      double sigma, vtkIdType *map)
+    {
+      RemoveOutliers remove(mean, sigma, distances, map);
+      vtkSMPTools::For(0, numPts, remove);
+    }
+
+}; //RemoveOutliers
+
+
+} //anonymous namespace
+
+
+//================= Begin class proper =======================================
+//----------------------------------------------------------------------------
+vtkStatisticalOutlierRemoval::vtkStatisticalOutlierRemoval()
+{
+  this->SampleSize = 25;
+  this->StandardDeviationFactor = 1.0;
+  this->Locator = vtkStaticPointLocator::New();
+
+  this->ComputedMean = 0.0;
+  this->ComputedStandardDeviation = 0.0;
+
+}
+
+//----------------------------------------------------------------------------
+vtkStatisticalOutlierRemoval::~vtkStatisticalOutlierRemoval()
+{
+  this->SetLocator(NULL);
+}
+
+//----------------------------------------------------------------------------
+// Traverse all the input points and gather statistics about average distance
+// between them, and the standard deviation of variation. Then filter points
+// within a specified deviation from the mean.
+int vtkStatisticalOutlierRemoval::FilterPoints(vtkPointSet *input)
+{
+  // Perform the point removal
+  // Start by building the locator
+  if ( !this->Locator )
+    {
+    vtkErrorMacro(<<"Point locator required\n");
+    return 0;
+    }
+  this->Locator->SetDataSet(input);
+  this->Locator->BuildLocator();
+
+  // Compute statistics across the point cloud. Start my computing
+  // mean distance to N closest neighbors.
+  vtkIdType numPts = input->GetNumberOfPoints();
+  float *dist = new float [numPts];
+  void *inPtr = input->GetPoints()->GetVoidPointer(0);
+  double mean=0.0, sigma=0.0;
+  switch (input->GetPoints()->GetDataType())
+    {
+    vtkTemplateMacro(ComputeMeanDistance<VTK_TT>::
+                     Execute(this, numPts, (VTK_TT *)inPtr, dist, mean));
+    }
+
+  // At this point the mean distance for each point, and across the point
+  // cloud is known. Now compute global standard deviation.
+  ComputeStdDev::Execute(numPts, dist, mean, sigma);
+
+  // Finally filter the points based on specified deviation range.
+  RemoveOutliers::Execute(numPts, dist, mean,
+                          this->StandardDeviationFactor*sigma, this->PointMap);
+
+  // Assign derived variable
+  this->ComputedMean = mean;
+  this->ComputedStandardDeviation = sigma;
+
+  // Clean up
+  delete [] dist;
+
+  return 1;
+}
+
+//----------------------------------------------------------------------------
+void vtkStatisticalOutlierRemoval::PrintSelf(ostream& os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os,indent);
+
+  os << indent << "Sample Size: " << this->SampleSize << "\n";
+  os << indent << "Standard Deviation Factor: "
+     << this->StandardDeviationFactor << "\n";
+  os << indent << "Locator: " << this->Locator << "\n";
+
+  os << indent << "Computed Mean: " << this->ComputedMean << "\n";
+  os << indent << "Computed Standard Deviation: "
+     << this->ComputedStandardDeviation << "\n";
+}
diff --git a/Filters/Points/vtkStatisticalOutlierRemoval.h b/Filters/Points/vtkStatisticalOutlierRemoval.h
new file mode 100644
index 0000000000000000000000000000000000000000..bdcc3cc7cdfe93d378bb6eab1f029632d267202b
--- /dev/null
+++ b/Filters/Points/vtkStatisticalOutlierRemoval.h
@@ -0,0 +1,123 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkStatisticalOutlierRemoval.h
+
+  Copyright (c) Kitware, Inc.
+  All rights reserved.
+  See LICENSE file 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.
+
+=========================================================================*/
+// .NAME vtkStatisticalOutlierRemoval - remove sparse outlier points
+
+// .SECTION Description
+// The vtkStatisticalOutlierRemoval filter removes sparse outlier points
+// through statistical analysis. The average (mean) distance between points
+// in the point cloud is computed (taking a local sample size around each
+// point); followed by computation of the global standard deviation of
+// distances between points. This global, statistical information is compared
+// against the mean separation distance for each point; those points whose
+// average separation is greater than the user-specified variation in
+// a multiple of standard deviation are removed.
+//
+// Note that while any vtkPointSet type can be provided as input, the output is
+// represented by an explicit representation of points via a
+// vtkPolyData. This output polydata will populate its instance of vtkPoints,
+// but no cells will be defined (i.e., no vtkVertex or vtkPolyVertex are
+// contained in the output). Also, after filter execution, the user can
+// request a vtkIdType* map which indicates how the input points were mapped
+// to the output. A value of map[i] (where i is the ith input point) less
+// than 0 means that the ith input point was removed. (See also the
+// superclass documentation for accessing the removed points through the
+// filter's second output.)
+
+// .SECTION Caveats
+// This class has been threaded with vtkSMPTools. Using TBB or other
+// non-sequential type (set in the CMake variable
+// VTK_SMP_IMPLEMENTATION_TYPE) may improve performance significantly.
+
+// .SECTION See Also
+// vtkPointCloudFilter vtkRadiusOutlierRemoval vtkExtractPoints
+// vtkThresholdPoints
+
+#ifndef vtkStatisticalOutlierRemoval_h
+#define vtkStatisticalOutlierRemoval_h
+
+#include "vtkFiltersPointsModule.h" // For export macro
+#include "vtkPointCloudFilter.h"
+
+class vtkAbstractPointLocator;
+class vtkPointSet;
+
+
+class VTKFILTERSPOINTS_EXPORT vtkStatisticalOutlierRemoval : public vtkPointCloudFilter
+{
+public:
+  // Description:
+  // Standard methods for instantiating, obtaining type information, and
+  // printing information.
+  static vtkStatisticalOutlierRemoval *New();
+  vtkTypeMacro(vtkStatisticalOutlierRemoval,vtkPointCloudFilter);
+  void PrintSelf(ostream& os, vtkIndent indent);
+
+  // Description:
+  // For each point sampled, specify the number of the closest, surrounding
+  // points used to compute statistics. By default 25 points are used. Smaller
+  // numbers may speed performance.
+  vtkSetClampMacro(SampleSize,int,1,VTK_INT_MAX);
+  vtkGetMacro(SampleSize,int);
+
+  // Description:
+  // The filter uses this specified standard deviation factor to extract
+  // points. By default, points within 1.0 standard deviations (i.e., a
+  // StandardDeviationFactor=1.0) of the mean distance to neighboring
+  // points are retained.
+  vtkSetClampMacro(StandardDeviationFactor,double,0.0,VTK_FLOAT_MAX);
+  vtkGetMacro(StandardDeviationFactor,double);
+
+  // Description:
+  // Specify a point locator. By default a vtkStaticPointLocator is
+  // used. The locator performs efficient searches to locate points
+  // surroinding a sample point.
+  void SetLocator(vtkAbstractPointLocator *locator);
+  vtkGetObjectMacro(Locator,vtkAbstractPointLocator);
+
+  // Description:
+  // After execution, return the value of the computed mean. Before execution
+  // the value returned is invalid.
+  vtkSetClampMacro(ComputedMean,double,0.0,VTK_FLOAT_MAX);
+  vtkGetMacro(ComputedMean,double);
+
+  // Description:
+  // After execution, return the value of the computed sigma (standard
+  // deviation). Before execution the value returned is invalid.
+  vtkSetClampMacro(ComputedStandardDeviation,double,0.0,VTK_FLOAT_MAX);
+  vtkGetMacro(ComputedStandardDeviation,double);
+
+protected:
+  vtkStatisticalOutlierRemoval();
+  ~vtkStatisticalOutlierRemoval();
+
+  int SampleSize;
+  double StandardDeviationFactor;
+  vtkAbstractPointLocator *Locator;
+
+  // Derived quantities
+  double ComputedMean;
+  double ComputedStandardDeviation;
+
+  // All derived classes must implement this method. Note that a side effect of
+  // the class is to populate the PointMap. Zero is returned if there is a failure.
+  virtual int FilterPoints(vtkPointSet *input);
+
+private:
+  vtkStatisticalOutlierRemoval(const vtkStatisticalOutlierRemoval&) VTK_DELETE_FUNCTION;
+  void operator=(const vtkStatisticalOutlierRemoval&) VTK_DELETE_FUNCTION;
+
+};
+
+#endif
diff --git a/Filters/Points/vtkVoxelGrid.cxx b/Filters/Points/vtkVoxelGrid.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..5951bc7ea74e56573a33e6c080942cf58449511f
--- /dev/null
+++ b/Filters/Points/vtkVoxelGrid.cxx
@@ -0,0 +1,299 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkVoxelGrid.cxx
+
+  Copyright (c) Kitware, Inc.
+  All rights reserved.
+  See LICENSE file 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.
+
+=========================================================================*/
+#include "vtkVoxelGrid.h"
+
+#include "vtkObjectFactory.h"
+#include "vtkDoubleArray.h"
+#include "vtkPointSet.h"
+#include "vtkPointData.h"
+#include "vtkPoints.h"
+#include "vtkStaticPointLocator.h"
+#include "vtkLinearKernel.h"
+#include "vtkInformation.h"
+#include "vtkInformationVector.h"
+#include "vtkStreamingDemandDrivenPipeline.h"
+#include "vtkSMPTools.h"
+#include "vtkSMPThreadLocalObject.h"
+#include "vtkArrayListTemplate.h" // For processing attribute data
+
+
+vtkStandardNewMacro(vtkVoxelGrid);
+vtkCxxSetObjectMacro(vtkVoxelGrid,Kernel,vtkInterpolationKernel);
+
+//----------------------------------------------------------------------------
+// Helper classes to support efficient computing, and threaded execution.
+namespace {
+
+//----------------------------------------------------------------------------
+// The threaded core of the algorithm (first pass)
+template <typename T>
+struct Subsample
+{
+  T *InPoints;
+  vtkStaticPointLocator *Locator;
+  vtkInterpolationKernel *Kernel;
+  const vtkIdType *BinMap;
+  ArrayList Arrays;
+  T *OutPoints;
+
+  // Don't want to allocate working arrays on every thread invocation. Thread local
+  // storage prevents lots of new/delete.
+  vtkSMPThreadLocalObject<vtkIdList> PIds;
+  vtkSMPThreadLocalObject<vtkDoubleArray> Weights;
+
+  Subsample(T* inPts, vtkPointData *inPD, vtkPointData *outPD,
+            vtkStaticPointLocator *loc, vtkInterpolationKernel *k,
+            vtkIdType nBins, vtkIdType *binMap, T *outPts) :
+    InPoints(inPts), Locator(loc), Kernel(k), BinMap(binMap), OutPoints(outPts)
+    {
+      this->Arrays.AddArrays(nBins, inPD, outPD);
+    }
+
+  // Just allocate a little bit of memory to get started.
+  void Initialize()
+    {
+    vtkIdList*& pIds = this->PIds.Local();
+    pIds->Allocate(128); //allocate some memory
+    vtkDoubleArray*& weights = this->Weights.Local();
+    weights->Allocate(128);
+    }
+
+  void operator() (vtkIdType binId, vtkIdType endBinId)
+    {
+      T *px;
+      T *py = this->OutPoints + 3*binId;
+      const vtkIdType *map = this->BinMap;
+      vtkIdList*& pIds = this->PIds.Local();
+      vtkIdType numWeights;
+      vtkDoubleArray*& weights = this->Weights.Local();
+      double y[3], count;
+      vtkIdType numIds, id;
+      vtkStaticPointLocator *loc = this->Locator;
+
+      for ( ; binId < endBinId; ++binId )
+        {
+        if ( map[binId] >= 0 )
+          {
+          y[0] = y[1] = y[2] = 0.0;
+          loc->GetBucketIds(binId,pIds);
+          numIds = pIds->GetNumberOfIds();
+          for (id=0; id < numIds; ++id)
+            {
+            px = this->InPoints + 3*pIds->GetId(id);
+            y[0] += *px++;
+            y[1] += *px++;
+            y[2] += *px;
+            }
+          count = static_cast<double>(numIds);
+          y[0] /= count;
+          y[1] /= count;
+          y[2] /= count;
+          *py++ = y[0];
+          *py++ = y[1];
+          *py++ = y[2];
+
+          // Now interpolate attributes
+          numWeights = this->Kernel->ComputeWeights(y, pIds, weights);
+          this->Arrays.Interpolate(numWeights, pIds->GetPointer(0),
+                                   weights->GetPointer(0), binId);
+          }// if occupied bin
+        }//for all bins in this batch
+    }
+
+  void Reduce()
+    {
+    }
+
+  static void Execute(T *inPts, vtkPointData *inPD, vtkPointData *outPD,
+                      vtkStaticPointLocator *loc, vtkInterpolationKernel *k,
+                      vtkIdType numBins, vtkIdType *binMap, T *outPts)
+    {
+      Subsample subsample(inPts, inPD, outPD, loc, k, numBins, binMap, outPts);
+      vtkSMPTools::For(0, numBins, subsample);
+    }
+
+}; //Subsample
+
+} //anonymous namespace
+
+
+//================= Begin class proper =======================================
+//----------------------------------------------------------------------------
+vtkVoxelGrid::vtkVoxelGrid()
+{
+  this->Locator = vtkStaticPointLocator::New();
+  this->ConfigurationStyle = vtkVoxelGrid::AUTOMATIC;
+
+  this->Divisions[0] = this->Divisions[1] = this->Divisions[2] = 50;
+  this->LeafSize[0] = this->LeafSize[1] = this->LeafSize[2] = 1.0;
+  this->NumberOfPointsPerBin = 10;
+
+  this->Kernel = vtkLinearKernel::New();
+}
+
+//----------------------------------------------------------------------------
+vtkVoxelGrid::~vtkVoxelGrid()
+{
+  this->Locator->Delete();
+  this->SetKernel(NULL);
+}
+
+//----------------------------------------------------------------------------
+// Produce the output data
+int vtkVoxelGrid::RequestData(
+  vtkInformation *vtkNotUsed(request),
+  vtkInformationVector **inputVector,
+  vtkInformationVector *outputVector)
+{
+  // get the info objects
+  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
+  vtkInformation *outInfo = outputVector->GetInformationObject(0);
+
+  // get the input and output
+  vtkPointSet *input = vtkPointSet::SafeDownCast(
+    inInfo->Get(vtkDataObject::DATA_OBJECT()));
+  vtkPolyData *output = vtkPolyData::SafeDownCast(
+    outInfo->Get(vtkDataObject::DATA_OBJECT()));
+
+  // Check the input
+  if ( !input || !output )
+    {
+    return 1;
+    }
+  vtkIdType numPts = input->GetNumberOfPoints();
+  if ( numPts < 1 )
+    {
+    return 1;
+    }
+
+  // Make sure there is a kernel
+  if ( !this->Kernel )
+    {
+    vtkErrorMacro(<<"Interpolation kernel required\n");
+    return 1;
+    }
+
+  bool valid = 1;
+  if ( this->LeafSize[0] <= 0.0 || this->LeafSize[1] <= 0.0 || this->LeafSize[2] <= 0.0 ||
+       this->Divisions[0] < 1 || this->Divisions[1] < 1 || this->Divisions[2] < 1 )
+    {
+    valid = false;
+    }
+
+  // Configure and build the locator
+  if ( valid && this->ConfigurationStyle == vtkVoxelGrid::MANUAL )
+    {
+    this->Locator->AutomaticOff();
+    this->Locator->SetDivisions(this->Divisions);
+    }
+  else if ( valid && this->ConfigurationStyle == vtkVoxelGrid::SPECIFY_LEAF_SIZE )
+    {
+    double bounds[6];
+    int divs[3];
+    this->Locator->AutomaticOff();
+    input->GetBounds(bounds);
+    divs[0] = (bounds[1]-bounds[0]) / this->LeafSize[0];
+    divs[1] = (bounds[3]-bounds[2]) / this->LeafSize[1];
+    divs[2] = (bounds[5]-bounds[4]) / this->LeafSize[2];
+    this->Locator->SetDivisions(divs);
+    }
+  else // this->ConfigurationStyle == vtkVoxelGrid::AUTOMATIC
+    {
+    this->Locator->AutomaticOn();
+    this->Locator->SetNumberOfPointsPerBucket(this->NumberOfPointsPerBin);
+    }
+  this->Locator->SetDataSet(input);
+  this->Locator->BuildLocator();
+
+  // Run through the locator and compute the number of output points,
+  // and build a map of the bin number to output point. This is a prefix sum.
+  vtkIdType numOutPts=0;
+  vtkIdType binNum, numBins = this->Locator->GetNumberOfBuckets();
+  vtkIdType *binMap = new vtkIdType [numBins];
+  for ( binNum=0; binNum < numBins; ++binNum )
+    {
+    if ( this->Locator->GetNumberOfPointsInBucket(binNum) > 0 )
+      {
+      binMap[binNum] = numOutPts++;
+      }
+    else
+      {
+      binMap[binNum] = -1;
+      }
+    }
+
+  // Grab the point data for interpolation
+  vtkPointData *inPD = input->GetPointData();
+  vtkPointData *outPD = output->GetPointData();
+  outPD->InterpolateAllocate(inPD,numBins);
+
+  // Finally run over all of the bins, and those that are not emoty are
+  // processed. The processing consists of averaging all of the points found
+  // in the bin, and setting the average point position in the output points.
+  vtkPoints *points = input->GetPoints()->NewInstance();
+  points->SetDataType(input->GetPoints()->GetDataType());
+  points->SetNumberOfPoints(numOutPts);
+  output->SetPoints(points);
+
+  void *inPtr = input->GetPoints()->GetVoidPointer(0);
+  void *outPtr = output->GetPoints()->GetVoidPointer(0);
+  switch (output->GetPoints()->GetDataType())
+    {
+    vtkTemplateMacro(Subsample<VTK_TT>::Execute((VTK_TT *)inPtr, inPD, outPD,
+            this->Locator, this->Kernel, numBins, binMap, (VTK_TT *)outPtr));
+    }
+
+  // Send attributes to output
+  int numPtArrays = input->GetPointData()->GetNumberOfArrays();
+  for (int i=0; i<numPtArrays; ++i)
+    {
+    output->GetPointData()->AddArray(input->GetPointData()->GetArray(i));
+    }
+
+  // Clean up
+  points->Delete();
+  delete [] binMap;
+
+  return 1;
+}
+
+//----------------------------------------------------------------------------
+int vtkVoxelGrid::
+FillInputPortInformation(int, vtkInformation *info)
+{
+  info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkPointSet");
+  return 1;
+}
+
+//----------------------------------------------------------------------------
+void vtkVoxelGrid::PrintSelf(ostream& os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os,indent);
+
+  os << indent << "Configuration Style: " << this->ConfigurationStyle << endl;
+
+  os << indent << "Divisions: ("
+     << this->Divisions[0] << ","
+     << this->Divisions[1] << ","
+     << this->Divisions[2] << ")\n";
+
+  os << indent << "Leaf Size: ("
+     << this->LeafSize[0] << ","
+     << this->LeafSize[1] << ","
+     << this->LeafSize[2] << ")\n";
+
+  os << indent << "Number of Points Per Bin: "
+     << this->NumberOfPointsPerBin << endl;
+}
diff --git a/Filters/Points/vtkVoxelGrid.h b/Filters/Points/vtkVoxelGrid.h
new file mode 100644
index 0000000000000000000000000000000000000000..c0356504b1d6bdcb8771b5192aa11d5c6dd41f0f
--- /dev/null
+++ b/Filters/Points/vtkVoxelGrid.h
@@ -0,0 +1,141 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkVoxelGrid.h
+
+  Copyright (c) Kitware, Inc.
+  All rights reserved.
+  See LICENSE file 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.
+
+=========================================================================*/
+// .NAME vtkVoxelGrid - subsample points using uniform binning
+
+// .SECTION Description
+// vtkVoxelGrid is a filter that subsamples a point cloud based on a regular
+// binning of space. Basically the algorithm operates by dividing space into
+// a volume of M x N x O bins, and then for each bin averaging all of the
+// points positions into a single representive point. Several strategies for
+// computing the binning can be used: 1) manual configuration of a requiring
+// specifying bin dimensions (the bounds are calculated from the data); 2) by
+// explicit specification of the bin size in world coordinates (x-y-z
+// lengths); and 3) an automatic process in which the user specifies an
+// approximate, average number of points per bin and dimensions and bin size
+// are computed automatically. (Note that under the hood a
+// vtkStaticPointLocator is used.)
+//
+// While any vtkPointSet type can be provided as input, the output is
+// represented by an explicit representation of points via a
+// vtkPolyData. This output polydata will populate its instance of vtkPoints,
+// but no cells will be defined (i.e., no vtkVertex or vtkPolyVertex are
+// contained in the output).
+
+// .SECTION Caveats
+// This class has been threaded with vtkSMPTools. Using TBB or other
+// non-sequential type (set in the CMake variable
+// VTK_SMP_IMPLEMENTATION_TYPE) may improve performance significantly.
+
+// .SECTION See Also
+// vtkStaticPointLocator vtkPointCloudFilter vtkQuadricClustering
+
+#ifndef vtkVoxelGrid_h
+#define vtkVoxelGrid_h
+
+#include "vtkFiltersPointsModule.h" // For export macro
+#include "vtkPolyDataAlgorithm.h"
+
+class vtkStaticPointLocator;
+class vtkInterpolationKernel;
+
+
+class VTKFILTERSPOINTS_EXPORT vtkVoxelGrid : public vtkPolyDataAlgorithm
+{
+public:
+  // Description:
+  // Standard methods for instantiating, obtaining type information, and
+  // printing information.
+  static vtkVoxelGrid *New();
+  vtkTypeMacro(vtkVoxelGrid,vtkPolyDataAlgorithm);
+  void PrintSelf(ostream& os, vtkIndent indent);
+
+  // Description:
+  // This enum is used to configure the operation of the filter.
+  enum Style
+  {
+    MANUAL=0,
+    SPECIFY_LEAF_SIZE=1,
+    AUTOMATIC=2
+  };
+
+  // Description:
+  // Configure how the filter is to operate. The user can choose to manually
+  // specify the binning volume (by setting its dimensions via MANUAL style); or
+  // specify a leaf bin size in the x-y-z directions (SPECIFY_LEAF_SIZE); or
+  // in AUTOMATIC style, use a rough average number of points in each bin
+  // guide the bin size and binning volume dimensions. By default, AUTOMATIC
+  // configuration style is used.
+  vtkSetMacro(ConfigurationStyle,int);
+  vtkGetMacro(ConfigurationStyle,int);
+  void SetConfigurationStyleToManual()
+    { this->SetConfigurationStyle(MANUAL); }
+  void SetConfigurationStyleToLeafSize()
+    { this->SetConfigurationStyle(SPECIFY_LEAF_SIZE); }
+  void SetConfigurationStyleToAutomatic()
+    { this->SetConfigurationStyle(AUTOMATIC); }
+
+  // Description:
+  // Set the number of divisions in x-y-z directions (the binning volume
+  // dimensions). This data member is used when the configuration style is
+  // set to MANUAL.
+  vtkSetVector3Macro(Divisions,int);
+  vtkGetVectorMacro(Divisions,int,3);
+
+  // Description:
+  // Set the bin size in the x-y-z directions. This data member is
+  // used when the configuration style is set to SPECIFY_LEAF_SIZE. The class will
+  // use these x-y-z lengths, within the bounding box of the point cloud,
+  // to determine the binning dimensions.
+  vtkSetVector3Macro(LeafSize,double);
+  vtkGetVectorMacro(LeafSize,double,3);
+
+  // Description:
+  // Specify the average number of points in each bin. Larger values
+  // result in higher rates of subsampling. This data member is used when the
+  // configuration style is set to AUTOMATIC. The class will automatically
+  // determine the binning dimensions in the x-y-z directions.
+  vtkSetClampMacro(NumberOfPointsPerBin,int,1,VTK_INT_MAX);
+  vtkGetMacro(NumberOfPointsPerBin,int);
+
+  // Description:
+  // Specify an interpolation kernel to combine the point attributes. By
+  // default a vtkLinearKernel is used (i.e., average values). The
+  // interpolation kernel changes the basis of the interpolation.
+  void SetKernel(vtkInterpolationKernel *kernel);
+  vtkGetObjectMacro(Kernel,vtkInterpolationKernel);
+
+protected:
+  vtkVoxelGrid();
+  ~vtkVoxelGrid();
+
+  vtkStaticPointLocator *Locator;
+  int ConfigurationStyle;
+
+  int Divisions[3];
+  double LeafSize[3];
+  int NumberOfPointsPerBin;
+  vtkInterpolationKernel *Kernel;
+
+  virtual int RequestData(vtkInformation *, vtkInformationVector **,
+                          vtkInformationVector *);
+  virtual int FillInputPortInformation(int port, vtkInformation *info);
+
+private:
+  vtkVoxelGrid(const vtkVoxelGrid&) VTK_DELETE_FUNCTION;
+  void operator=(const vtkVoxelGrid&) VTK_DELETE_FUNCTION;
+
+};
+
+#endif
diff --git a/Remote/point-cloud.remote.cmake b/Remote/point-cloud.remote.cmake
deleted file mode 100644
index 502b6a50e397840578bdaf5167b91c97d7840854..0000000000000000000000000000000000000000
--- a/Remote/point-cloud.remote.cmake
+++ /dev/null
@@ -1,10 +0,0 @@
-#
-# vtkPointCloud - specialized filters for processing point clouds
-#   GIT_REPOSITORY git@gitlab.kitware.com:vtk/point-cloud.git
-
-
-vtk_fetch_module(vtkPointCloud
-  "Point Cloud processing in VTK"
-  GIT_REPOSITORY https://gitlab.kitware.com/vtk/point-cloud.git
-  GIT_TAG master
-  )