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()