diff --git a/src/Cxx.md b/src/Cxx.md
index 2d6b978078b52ff9b570c83d62963c7241eea2a3..86c6ce0dbf7331c79868b2f4daec82bdf8f8e9cd 100644
--- a/src/Cxx.md
+++ b/src/Cxx.md
@@ -920,6 +920,7 @@ See [this tutorial](http://www.vtk.org/Wiki/VTK/Tutorials/3DDataTypes) for a bri
 [VectorOfActors](/Cxx/Visualization/VectorOfActors)| vtkActor |Multiple Actors in a Vector.
 [VectorText](/Cxx/Visualization/VectorText)| vtkVectorText |Display high resolution text.
 [VertexGlyphFilter](/Cxx/Filtering/VertexGlyphFilter) | vtkVertexGlyphFilter | Add a vertex to each point.
+[VelocityProfile](/Cxx/VisualizationAlgorithms/VelocityProfile) | vtkMultiBlockPLOT3DReader vtkStructuredGridGeometryFilter vtkAppendPolyData vtkWarpVector | Warping the geometry of three planes to show flow momentum.
 [Visualize2DPoints](/Cxx/Visualization/Visualize2DPoints)| vtkPolyDataMapper2D vtkProperty2D | Visualize a 2D Set of Points.
 [VisualizeImageData](/Cxx/Visualization/VisualizeImageData)| vtkDataSetMapper | Visualize the points of an ImageData.
 [VisualizeVTP](/Cxx/Visualization/VisualizeVTP)| vtkXMLPolyDataReader vtkPolyDataMapper | Visualize a VTP File.
diff --git a/src/Cxx/VisualizationAlgorithms/CMakeLists.txt b/src/Cxx/VisualizationAlgorithms/CMakeLists.txt
index 3f6d73bf8025fb4d570e1bda2bb9d47c294b58d5..70e69a4ba6be9f4355347a8cfbe90630543eae66 100644
--- a/src/Cxx/VisualizationAlgorithms/CMakeLists.txt
+++ b/src/Cxx/VisualizationAlgorithms/CMakeLists.txt
@@ -40,6 +40,7 @@ set(NEEDS_ARGS
   MarchingCasesB
   PlateVibration
   SpikeFran
+  VelocityProfile
   WarpCombustor
 )
 set(DATA ${WikiExamples_SOURCE_DIR}/src/Testing/Data)
@@ -101,6 +102,9 @@ add_test(${KIT}-PlateVibration ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${KIT}CxxTests
 add_test(${KIT}-SpikeFran ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${KIT}CxxTests
   TestSpikeFran ${DATA}/fran_cut.vtk)
 
+add_test(${KIT}-VelocityProfile ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${KIT}CxxTests
+  TestVelocityProfile ${DATA}/combxyz.bin ${DATA}/combq.bin)
+
 add_test(${KIT}-WarpCombustor ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${KIT}CxxTests
   TestWarpCombustor ${DATA}/combxyz.bin ${DATA}/combq.bin)
 
diff --git a/src/Cxx/VisualizationAlgorithms/VelocityProfile.cxx b/src/Cxx/VisualizationAlgorithms/VelocityProfile.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..2d6044e53fed7cd778a746903c58746c66f0e067
--- /dev/null
+++ b/src/Cxx/VisualizationAlgorithms/VelocityProfile.cxx
@@ -0,0 +1,158 @@
+// Translated from velProf.tcl.
+
+#include <vtkActor.h>
+#include <vtkAppendPolyData.h>
+#include <vtkCamera.h>
+#include <vtkLookupTable.h>
+#include <vtkMultiBlockDataSet.h>
+#include <vtkMultiBlockPLOT3DReader.h>
+#include <vtkNamedColors.h>
+#include <vtkPolyDataMapper.h>
+#include <vtkProperty.h>
+#include <vtkRenderWindow.h>
+#include <vtkRenderWindowInteractor.h>
+#include <vtkRenderer.h>
+#include <vtkSmartPointer.h>
+#include <vtkStructuredGrid.h>
+#include <vtkStructuredGridGeometryFilter.h>
+#include <vtkStructuredGridOutlineFilter.h>
+#include <vtkWarpVector.h>
+
+#include <algorithm>
+#include <string>
+#include <vector>
+
+int main(int argc, char* argv[])
+{
+  auto Scale = [](std::vector<double>& v, double scale) {
+    std::transform(std::begin(v), std::end(v), std::begin(v),
+                   [=](double const& n) { return n / scale; });
+    return;
+  };
+
+  if (argc < 2)
+  {
+    std::cout << "Usage: " << argv[0] << " filename1 filename2" << std::endl;
+    std::cout << "where: filename1 is combxyz.bin and filename2 is combq.bin."
+              << std::endl;
+    std::cout << "Produces figure 6-14(b) Flow momentum from the VTK Textbook."
+              << std::endl;
+    return EXIT_FAILURE;
+  }
+
+  std::string fileName1 = argv[1];
+  std::string fileName2 = argv[2];
+
+  vtkSmartPointer<vtkNamedColors> colors =
+    vtkSmartPointer<vtkNamedColors>::New();
+  // Set the background color, match those in VTKTextbook.pdf.
+  auto scale = 256.0;
+  std::vector<double> bkg = {65, 99, 149};
+  Scale(bkg, scale);
+  colors->SetColor("BkgColor", bkg[0], bkg[1], bkg[2]);
+
+  // Read a vtk file
+  //
+  vtkSmartPointer<vtkMultiBlockPLOT3DReader> pl3d =
+    vtkSmartPointer<vtkMultiBlockPLOT3DReader>::New();
+  pl3d->SetXYZFileName(fileName1.c_str());
+  pl3d->SetQFileName(fileName2.c_str());
+  pl3d->SetScalarFunctionNumber(100); // Density
+  pl3d->SetVectorFunctionNumber(202); // Momentum
+  pl3d->Update();
+
+  vtkStructuredGrid* pl3dOutput =
+    vtkStructuredGrid::SafeDownCast(pl3d->GetOutput()->GetBlock(0));
+
+  // What do we know about the data?
+  // Get the extent of the data: imin,imax, jmin,jmax, kmin,kmax
+  int extent[6] = {0, 0, 0, 0, 0, 0};
+  pl3dOutput->GetExtent(extent);
+  double scalarRange[2] = {0.0, 0.0};
+  pl3dOutput->GetScalarRange(scalarRange);
+
+  // Planes are specified using a imin,imax, jmin,jmax, kmin,kmax coordinate
+  // specification. Min and max i,j,k values are clamped to 0 and maximum value.
+  // See the variable named extent for the values.
+  //
+  vtkSmartPointer<vtkStructuredGridGeometryFilter> plane =
+    vtkSmartPointer<vtkStructuredGridGeometryFilter>::New();
+  plane->SetInputData(pl3dOutput);
+  plane->SetExtent(10, 10, 1, extent[3], 1, extent[5]);
+
+  vtkSmartPointer<vtkStructuredGridGeometryFilter> plane2 =
+    vtkSmartPointer<vtkStructuredGridGeometryFilter>::New();
+  plane2->SetInputData(pl3dOutput);
+  plane2->SetExtent(30, 30, 1, extent[3], 1, extent[5]);
+
+  vtkSmartPointer<vtkStructuredGridGeometryFilter> plane3 =
+    vtkSmartPointer<vtkStructuredGridGeometryFilter>::New();
+  plane3->SetInputData(pl3dOutput);
+  plane3->SetExtent(45, 45, 1, extent[3], 1, extent[5]);
+
+  // We use an append filter because that way we can do the warping, etc. just
+  // using a single pipeline and actor.
+  //
+  vtkSmartPointer<vtkAppendPolyData> appendF =
+    vtkSmartPointer<vtkAppendPolyData>::New();
+  appendF->AddInputConnection(plane->GetOutputPort());
+  appendF->AddInputConnection(plane2->GetOutputPort());
+  appendF->AddInputConnection(plane3->GetOutputPort());
+
+  // Warp
+  vtkSmartPointer<vtkWarpVector> warp = vtkSmartPointer<vtkWarpVector>::New();
+  warp->SetInputConnection(appendF->GetOutputPort());
+  warp->SetScaleFactor(0.005);
+
+  vtkSmartPointer<vtkPolyDataMapper> planeMapper =
+    vtkSmartPointer<vtkPolyDataMapper>::New();
+  planeMapper->SetInputConnection(warp->GetOutputPort());
+  planeMapper->SetScalarRange(scalarRange);
+
+  vtkSmartPointer<vtkActor> planeActor = vtkSmartPointer<vtkActor>::New();
+  planeActor->SetMapper(planeMapper);
+
+  // The outline provides context for the data and the planes.
+  vtkSmartPointer<vtkStructuredGridOutlineFilter> outline =
+    vtkSmartPointer<vtkStructuredGridOutlineFilter>::New();
+  outline->SetInputData(pl3dOutput);
+
+  vtkSmartPointer<vtkPolyDataMapper> outlineMapper =
+    vtkSmartPointer<vtkPolyDataMapper>::New();
+  outlineMapper->SetInputConnection(outline->GetOutputPort());
+
+  vtkSmartPointer<vtkActor> outlineActor = vtkSmartPointer<vtkActor>::New();
+  outlineActor->SetMapper(outlineMapper);
+  outlineActor->GetProperty()->SetColor(colors->GetColor3d("Black").GetData());
+
+  // Create the RenderWindow, Renderer and both Actors
+  //
+  vtkSmartPointer<vtkRenderer> ren = vtkSmartPointer<vtkRenderer>::New();
+  vtkSmartPointer<vtkRenderWindow> renWin =
+    vtkSmartPointer<vtkRenderWindow>::New();
+  renWin->AddRenderer(ren);
+
+  vtkSmartPointer<vtkRenderWindowInteractor> iren =
+    vtkSmartPointer<vtkRenderWindowInteractor>::New();
+  iren->SetRenderWindow(renWin);
+
+  // Add the actors to the renderer, set the background and size
+  //
+  ren->AddActor(planeActor);
+  ren->AddActor(outlineActor);
+  ren->SetBackground(colors->GetColor3d("BkgColor").GetData());
+  renWin->SetSize(512, 512);
+
+  iren->Initialize();
+
+  renWin->Render();
+
+  ren->GetActiveCamera()->SetPosition(19.8562, -31.8912, 47.0755);
+  ren->GetActiveCamera()->SetFocalPoint(8.255, 0.147815, 29.7631);
+  ren->GetActiveCamera()->SetViewUp(-0.0333325, 0.465756, 0.884285);
+  ren->GetActiveCamera()->SetClippingRange(17.3078, 64.6375);
+
+  iren->Start();
+
+  return EXIT_SUCCESS;
+}
diff --git a/src/Cxx/VisualizationAlgorithms/VelocityProfile.md b/src/Cxx/VisualizationAlgorithms/VelocityProfile.md
new file mode 100644
index 0000000000000000000000000000000000000000..ad784ba3dda75f446a5f646c46ed9dcd7d3b0a38
--- /dev/null
+++ b/src/Cxx/VisualizationAlgorithms/VelocityProfile.md
@@ -0,0 +1,3 @@
+### Description
+This example shows shows warped planes in a structured grid dataset. The planes are warped according to flow
+momentum. The relative back and forward flow are clearly visible in the deformation of the planes.
\ No newline at end of file
diff --git a/src/Python.md b/src/Python.md
index 9e7e88ac03d285387c6c7a8676c6da908ba95987..2f2a8f06cc0e2be4e17d804c9c7dcfceb0e74370 100644
--- a/src/Python.md
+++ b/src/Python.md
@@ -200,6 +200,7 @@ This section includes examples of manipulating meshes.
 [Streamlines](/Python/Visualization/Streamlines) | vtkStreamLine | Seed streamlines with vectors from a structured grid
 [TextSource](/Python/Visualization/TextSource) | vtkTextSource |
 [UnstructuredTransientVolumeRendering](/Python/Visualization/UnstructuredTransientVolumeRendering) | vtkUnstructuredGridVolumeRayCastMapper |
+[VelocityProfile](/Python/VisualizationAlgorithms/VelocityProfile) | vtkMultiBlockPLOT3DReader vtkStructuredGridGeometryFilter vtkAppendPolyData vtkWarpVector | Warping the geometry of three planes to show flow momentum.
 [VectorText](/Python/Visualization/VectorText)| vtkVectorText |Display high resolution text.
 [WindowTitle](/Python/Visualization/WindowTitle) | vtkRenderWindow::SetWindowName |
 
diff --git a/src/Python/VisualizationAlgorithms/VelocityProfile.md b/src/Python/VisualizationAlgorithms/VelocityProfile.md
new file mode 100644
index 0000000000000000000000000000000000000000..ad784ba3dda75f446a5f646c46ed9dcd7d3b0a38
--- /dev/null
+++ b/src/Python/VisualizationAlgorithms/VelocityProfile.md
@@ -0,0 +1,3 @@
+### Description
+This example shows shows warped planes in a structured grid dataset. The planes are warped according to flow
+momentum. The relative back and forward flow are clearly visible in the deformation of the planes.
\ No newline at end of file
diff --git a/src/Python/VisualizationAlgorithms/VelocityProfile.py b/src/Python/VisualizationAlgorithms/VelocityProfile.py
new file mode 100644
index 0000000000000000000000000000000000000000..c46fc556c9f33426d6d060cabd3a7939c21b73ca
--- /dev/null
+++ b/src/Python/VisualizationAlgorithms/VelocityProfile.py
@@ -0,0 +1,120 @@
+# Translated from velProf.tcl.
+
+import vtk
+
+
+def main():
+    fileName1, fileName2 = get_program_parameters()
+
+    colors = vtk.vtkNamedColors()
+    # Set the background color. Match those in VTKTextbook.pdf.
+    bkg = map(lambda x: x / 256.0, [65, 99, 149])
+    colors.SetColor("BkgColor", *bkg)
+
+    # Read a vtk file
+    #
+    pl3d = vtk.vtkMultiBlockPLOT3DReader()
+    pl3d.SetXYZFileName(fileName1)
+    pl3d.SetQFileName(fileName2)
+    pl3d.SetScalarFunctionNumber(100)  # Density
+    pl3d.SetVectorFunctionNumber(202)  # Momentum
+    pl3d.Update()
+
+    pl3dOutput = pl3d.GetOutput().GetBlock(0)
+
+    # What do we know about the data?
+    # Get the extent of the data: imin,imax, jmin,jmax, kmin,kmax
+    extent = pl3dOutput.GetExtent()
+    scalarRange = pl3dOutput.GetScalarRange()
+
+    # Planes are specified using a imin,imax, jmin,jmax, kmin,kmax coordinate
+    # specification. Min and max i,j,k values are clamped to 0 and maximum value.
+    # See the variable named extent for the values.
+    #
+    plane = vtk.vtkStructuredGridGeometryFilter()
+    plane.SetInputData(pl3dOutput)
+    plane.SetExtent(10, 10, 1, extent[3], 1, extent[5])
+
+    plane2 = vtk.vtkStructuredGridGeometryFilter()
+    plane2.SetInputData(pl3dOutput)
+    plane2.SetExtent(30, 30, 1, extent[3], 1, extent[5])
+
+    plane3 = vtk.vtkStructuredGridGeometryFilter()
+    plane3.SetInputData(pl3dOutput)
+    plane3.SetExtent(45, 45, 1, extent[3], 1, extent[5])
+
+    # We use an append filter because that way we can do the warping, etc. just
+    # using a single pipeline and actor.
+    #
+    appendF = vtk.vtkAppendPolyData()
+    appendF.AddInputConnection(plane.GetOutputPort())
+    appendF.AddInputConnection(plane2.GetOutputPort())
+    appendF.AddInputConnection(plane3.GetOutputPort())
+
+    # Warp
+    warp = vtk.vtkWarpVector()
+    warp.SetInputConnection(appendF.GetOutputPort())
+    warp.SetScaleFactor(0.005)
+
+    planeMapper = vtk.vtkPolyDataMapper()
+    planeMapper.SetInputConnection(warp.GetOutputPort())
+    planeMapper.SetScalarRange(scalarRange)
+
+    planeActor = vtk.vtkActor()
+    planeActor.SetMapper(planeMapper)
+
+    # The outline provides context for the data and the planes.
+    outline = vtk.vtkStructuredGridOutlineFilter()
+    outline.SetInputData(pl3dOutput)
+
+    outlineMapper = vtk.vtkPolyDataMapper()
+    outlineMapper.SetInputConnection(outline.GetOutputPort())
+
+    outlineActor = vtk.vtkActor()
+    outlineActor.SetMapper(outlineMapper)
+    outlineActor.GetProperty().SetColor(colors.GetColor3d("Black"))
+
+    # Create the RenderWindow, Renderer and both Actors
+    #
+    ren = vtk.vtkRenderer()
+    renWin = vtk.vtkRenderWindow()
+    renWin.AddRenderer(ren)
+
+    iren = vtk.vtkRenderWindowInteractor()
+    iren.SetRenderWindow(renWin)
+
+    # Add the actors to the renderer, set the background and size
+    #
+    ren.AddActor(planeActor)
+    ren.AddActor(outlineActor)
+    ren.SetBackground(colors.GetColor3d("BkgColor"))
+    renWin.SetSize(512, 512)
+
+    iren.Initialize()
+
+    renWin.Render()
+
+    ren.GetActiveCamera().SetPosition(19.8562, -31.8912, 47.0755)
+    ren.GetActiveCamera().SetFocalPoint(8.255, 0.147815, 29.7631)
+    ren.GetActiveCamera().SetViewUp(-0.0333325, 0.465756, 0.884285)
+    ren.GetActiveCamera().SetClippingRange(17.3078, 64.6375)
+
+    iren.Start()
+
+
+def get_program_parameters():
+    import argparse
+    description = 'Produce figure 6–14(b) Flow momentum from the VTK Textbook.'
+    epilogue = '''
+        Produce figure 6–14(b) Flow momentum from the VTK Textbook.
+
+   '''
+    parser = argparse.ArgumentParser(description=description, epilog=epilogue)
+    parser.add_argument('filename1', help='combxyz.bin.')
+    parser.add_argument('filename2', help='combq.bin.')
+    args = parser.parse_args()
+    return args.filename1, args.filename2
+
+
+if __name__ == '__main__':
+    main()