diff --git a/src/Cxx.md b/src/Cxx.md index 0046562ea888a81206b3bb0e1a5dfa2883aad7cc..383272f6119dd31a6cc9181278f4b2e95e63e342 100644 --- a/src/Cxx.md +++ b/src/Cxx.md @@ -885,6 +885,7 @@ See [this tutorial](http://www.vtk.org/Wiki/VTK/Tutorials/3DDataTypes) for a bri [LegendScaleActor](/Cxx/Visualization/LegendScaleActor)| vtkLegendScaleActor |Display the scale of a scene. [Legend](/Cxx/Visualization/Legend) | vtkLegendBoxActor | [LineWidth](/Cxx/Visualization/LineWidth)| vtkActor vtkProperty |Change the width/thickness of lines in an actor. +[Motor](/Cxx/VisualizationAlgorithms/Motor) | vtkBYUReader vtkStructuredPointsReader vtkTexture vtkImplicitTextureCoords | Texture cut used to reveal internal structure of a motor. Two cut planes are used in combination with transparent texture. [MovableAxes](/Cxx/Visualization/MovableAxes) | vtkFollower vtkAxesActor vtkAssembly | Movable axes. [MoveActor](/Cxx/Visualization/MoveActor)| vtkInteractorStyleTrackballActor |Moving an Actor. [MoveCamera](/Cxx/Visualization/MoveCamera)| vtkInteractorStyleTrackballCamera |Moving the Camera. diff --git a/src/Cxx/VisualizationAlgorithms/CMakeLists.txt b/src/Cxx/VisualizationAlgorithms/CMakeLists.txt index 00bbafa97de3b95a414ba099f388ae8dc3ec3c08..3ca4b20bde9743c164d3d99856507a1eef6c51b3 100644 --- a/src/Cxx/VisualizationAlgorithms/CMakeLists.txt +++ b/src/Cxx/VisualizationAlgorithms/CMakeLists.txt @@ -39,6 +39,7 @@ set(NEEDS_ARGS Hello IronIsoSurface LOx + Motor MarchingCases MarchingCasesA MarchingCasesB @@ -116,6 +117,9 @@ add_test(${KIT}-MarchingCasesA ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${KIT}CxxTests add_test(${KIT}-MarchingCasesB ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${KIT}CxxTests TestMarchingCasesB -3 -6 -7 -10 -12 -13) +add_test(${KIT}-Motor ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${KIT}CxxTests + TestMotor ${DATA}/texThres2.vtk ${DATA}/motor.g) + add_test(${KIT}-PlateVibration ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${KIT}CxxTests TestPlateVibration ${DATA}/plate.vtk) diff --git a/src/Cxx/VisualizationAlgorithms/Motor.cxx b/src/Cxx/VisualizationAlgorithms/Motor.cxx new file mode 100644 index 0000000000000000000000000000000000000000..aac7cfa512c98d36bd3170ca3d6d8fe23d2e799d --- /dev/null +++ b/src/Cxx/VisualizationAlgorithms/Motor.cxx @@ -0,0 +1,139 @@ +/* +This code is based on the VTK file: /IO/Geometry/Testing/Python/motor.py. +*/ + +#include <vtkActor.h> +#include <vtkBYUReader.h> +#include <vtkCamera.h> +#include <vtkDataSetMapper.h> +#include <vtkFloatArray.h> +#include <vtkImplicitTextureCoords.h> +#include <vtkNamedColors.h> +#include <vtkPlanes.h> +#include <vtkPoints.h> +#include <vtkPolyDataNormals.h> +#include <vtkProperty.h> +#include <vtkRenderWindow.h> +#include <vtkRenderWindowInteractor.h> +#include <vtkRenderer.h> +#include <vtkStructuredPointsReader.h> +#include <vtkTexture.h> + +#include <string> +#include <vector> + +int main(int argc, char* argv[]) +{ + if (argc < 3) + { + std::cout << "Usage: " << argv[0] << " textureFile motorFile" << std::endl; + std::cout << "where: textureFile is the texture file: texThres2.vtk." + << std::endl; + std::cout << " motorFile is ihe motor file: motor.g." << std::endl; + return EXIT_FAILURE; + } + + std::string textureFile = argv[1]; + std::string motorFile = argv[2]; + + vtkSmartPointer<vtkNamedColors> colors = + vtkSmartPointer<vtkNamedColors>::New(); + + // Create the Renderer, RenderWindow and RenderWindowInteractor. + vtkSmartPointer<vtkRenderer> ren = vtkSmartPointer<vtkRenderer>::New(); + vtkSmartPointer<vtkRenderWindow> renWin = + vtkSmartPointer<vtkRenderWindow>::New(); + renWin->AddRenderer(ren); + vtkSmartPointer<vtkRenderWindowInteractor> iren = + vtkSmartPointer<vtkRenderWindowInteractor>::New(); + iren->SetRenderWindow(renWin); + + // Create the cutting planes. + vtkSmartPointer<vtkPlanes> planes = vtkSmartPointer<vtkPlanes>::New(); + vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New(); + vtkSmartPointer<vtkFloatArray> norms = vtkSmartPointer<vtkFloatArray>::New(); + + norms->SetNumberOfComponents(3); + points->InsertPoint(0, 0.0, 0.0, 0.0); + norms->InsertTuple3(0, 0.0, 0.0, 1.0); + points->InsertPoint(1, 0.0, 0.0, 0.0); + norms->InsertTuple3(1, -1.0, 0.0, 0.0); + planes->SetPoints(points); + planes->SetNormals(norms); + + // Get the texture. + vtkSmartPointer<vtkStructuredPointsReader> texReader = + vtkSmartPointer<vtkStructuredPointsReader>::New(); + texReader->SetFileName(textureFile.c_str()); + vtkSmartPointer<vtkTexture> texture = vtkSmartPointer<vtkTexture>::New(); + texture->SetInputConnection(texReader->GetOutputPort()); + texture->InterpolateOff(); + texture->RepeatOff(); + + // Set up the pipelines for the parts of the motor. + // We will use lists of pipeline objects. + auto numberOfParts = 5; + std::vector<vtkSmartPointer<vtkBYUReader>> byu; + std::vector<vtkSmartPointer<vtkPolyDataNormals>> normals; + std::vector<vtkSmartPointer<vtkImplicitTextureCoords>> tex; + std::vector<vtkSmartPointer<vtkDataSetMapper>> byuMapper; + std::vector<vtkSmartPointer<vtkActor>> byuActor; + std::vector<std::string> partColours{"cold_grey", "peacock", "raw_sienna", + "banana", "peach_puff"}; + // Use this to control which parts to display. + std::vector<bool> displayParts(numberOfParts, true); + // If displayParts[2] = false; then an image like that in the VTK tests is + // produced. + + for (auto i = 0; i < numberOfParts; ++i) + { + byu.push_back(vtkSmartPointer<vtkBYUReader>::New()); + byu[i]->SetGeometryFileName(motorFile.c_str()); + byu[i]->SetPartNumber(i + 1); + + normals.push_back(vtkSmartPointer<vtkPolyDataNormals>::New()); + normals[i]->SetInputConnection(byu[i]->GetOutputPort()); + + tex.push_back(vtkSmartPointer<vtkImplicitTextureCoords>::New()); + tex[i]->SetInputConnection(normals[i]->GetOutputPort()); + tex[i]->SetRFunction(planes); + // tex[i]->FlipTextureOn(); + + byuMapper.push_back(vtkSmartPointer<vtkDataSetMapper>::New()); + byuMapper[i]->SetInputConnection(tex[i]->GetOutputPort()); + + byuActor.push_back(vtkSmartPointer<vtkActor>::New()); + byuActor[i]->SetMapper(byuMapper[i]); + byuActor[i]->SetTexture(texture); + byuActor[i]->GetProperty()->SetColor( + colors->GetColor3d(partColours[i]).GetData()); + + ren->AddActor(byuActor[i]); + if (displayParts[i]) + { + byuActor[i]->VisibilityOn(); + } + else + { + byuActor[i]->VisibilityOff(); + } + } + + ren->SetBackground(colors->GetColor3d("AliceBlue").GetData()); + + renWin->SetSize(512, 512); + + vtkSmartPointer<vtkCamera> camera = vtkSmartPointer<vtkCamera>::New(); + camera->SetFocalPoint(0.0286334, 0.0362996, 0.0379685); + camera->SetPosition(1.37067, 1.08629, -1.30349); + camera->SetViewAngle(17.673); + camera->SetClippingRange(1, 10); + camera->SetViewUp(-0.376306, -0.5085, -0.774482); + ren->SetActiveCamera(camera); + + // Render the image. + iren->Initialize(); + iren->Start(); + + return EXIT_SUCCESS; +} diff --git a/src/Cxx/VisualizationAlgorithms/Motor.md b/src/Cxx/VisualizationAlgorithms/Motor.md new file mode 100644 index 0000000000000000000000000000000000000000..e561a30ff0be6d4f5fd73fe4b731b5e429ec3da9 --- /dev/null +++ b/src/Cxx/VisualizationAlgorithms/Motor.md @@ -0,0 +1,6 @@ +### Description +This is an example of texture clipping using a transparent texture map. The motor shown consists of five complex parts, some of which are hidden by the outer casing. To see the inside of the motor, we define an implicit clipping function. This function is simply the intersection of two planes to form a clipping "corner". The object **vtkImplicitTextureCoords** is used in combination with this implicit function to generate texture coordinates. These objects are then rendered with the appropriate texture map and the internal parts of the motor can be seen. + +The texture map consists of three regions (as described previously in the chapter). The concealed region is transparent. The transition region is opaque but with a black (zero intensity) color. The highlighted region is full intensity and opaque. As can be seen from the result , the boundaries appear as black borders giving a nice visual effect. + +Note the use of vectors in the C++ version and lists in the Python version to reduce repetitious code. \ No newline at end of file diff --git a/src/Python.md b/src/Python.md index b8981a6bd9b313ab5f2433d7d1e57188da06b5d7..8a6c4afa2535137b40c36cf7c8753576f75f7810 100644 --- a/src/Python.md +++ b/src/Python.md @@ -190,6 +190,7 @@ This section includes examples of manipulating meshes. [HardwareSelector](/Python/Visualization/HardwareSelector) | vtkHardwareSelector | [InteractorStyleTrackballActor](/Python/Visualization/InteractorStyleTrackballActor) | vtkInteractorStyleTrackBallActor | [InteractorStyleTrackballCamera](/Python/Visualization/InteractorStyleTrackballCamera) | vtkInteractorStyleTrackBallCamera | +[Motor](/Python/VisualizationAlgorithms/Motor) | vtkBYUReader vtkStructuredPointsReader vtkTexture vtkImplicitTextureCoords | Texture cut used to reveal internal structure of a motor. Two cut planes are used in combination with transparent texture. [MultipleViewports](/Python/Visualization/MultipleViewports) | vtkRenderer::SetViewport | [NamedColors](/Python/Visualization/NamedColors) | vtkNamedColors | Demonstrates how to use the vtkNamedColors class. [NamedColorPatches](/Python/Visualization/NamedColorPatches) | vtkNamedColors | Creates a HTML file called [VTKNamedColorPatches](http://htmlpreview.github.com/?https://github.com/lorensen/VTKExamples/blob/master/src/Python/Visualization/VTKNamedColorPatches.html) diff --git a/src/Python/VisualizationAlgorithms/Motor.md b/src/Python/VisualizationAlgorithms/Motor.md new file mode 100644 index 0000000000000000000000000000000000000000..e561a30ff0be6d4f5fd73fe4b731b5e429ec3da9 --- /dev/null +++ b/src/Python/VisualizationAlgorithms/Motor.md @@ -0,0 +1,6 @@ +### Description +This is an example of texture clipping using a transparent texture map. The motor shown consists of five complex parts, some of which are hidden by the outer casing. To see the inside of the motor, we define an implicit clipping function. This function is simply the intersection of two planes to form a clipping "corner". The object **vtkImplicitTextureCoords** is used in combination with this implicit function to generate texture coordinates. These objects are then rendered with the appropriate texture map and the internal parts of the motor can be seen. + +The texture map consists of three regions (as described previously in the chapter). The concealed region is transparent. The transition region is opaque but with a black (zero intensity) color. The highlighted region is full intensity and opaque. As can be seen from the result , the boundaries appear as black borders giving a nice visual effect. + +Note the use of vectors in the C++ version and lists in the Python version to reduce repetitious code. \ No newline at end of file diff --git a/src/Python/VisualizationAlgorithms/Motor.py b/src/Python/VisualizationAlgorithms/Motor.py new file mode 100644 index 0000000000000000000000000000000000000000..6b8adfdb0a2c7eb8a7bd5757758ea0de1465ff04 --- /dev/null +++ b/src/Python/VisualizationAlgorithms/Motor.py @@ -0,0 +1,114 @@ +#!/usr/bin/env python + +# This code is based on the VTK file: /IO/Geometry/Testing/Python/motor.py. + +import vtk + + +def main(): + colors = vtk.vtkNamedColors() + + textureFile, motorFile = get_program_parameters() + + # Create the Renderer, RenderWindow and RenderWindowInteractor. + ren = vtk.vtkRenderer() + renWin = vtk.vtkRenderWindow() + renWin.AddRenderer(ren) + iren = vtk.vtkRenderWindowInteractor() + iren.SetRenderWindow(renWin) + + # Create the cutting planes. + planes = vtk.vtkPlanes() + points = vtk.vtkPoints() + norms = vtk.vtkFloatArray() + + norms.SetNumberOfComponents(3) + points.InsertPoint(0, 0.0, 0.0, 0.0) + norms.InsertTuple3(0, 0.0, 0.0, 1.0) + points.InsertPoint(1, 0.0, 0.0, 0.0) + norms.InsertTuple3(1, -1.0, 0.0, 0.0) + planes.SetPoints(points) + planes.SetNormals(norms) + + # Get the texture. + texReader = vtk.vtkStructuredPointsReader() + texReader.SetFileName(textureFile) + texture = vtk.vtkTexture() + texture.SetInputConnection(texReader.GetOutputPort()) + texture.InterpolateOff() + texture.RepeatOff() + + # Set up the pipelines for the parts of the motor. + # We will use lists of pipeline objects. + numberOfParts = 5 + byu = list() + normals = list() + tex = list() + byuMapper = list() + byuActor = list() + partColours = ['cold_grey', 'peacock', 'raw_sienna', 'banana', 'peach_puff'] + # Use this to control which parts to display. + displayParts = [True] * numberOfParts + # If displayParts[2] = False then an image like that in the VTK tests is produced. + + # Build the pipelines. + for i in range(0, numberOfParts): + byu.append(vtk.vtkBYUReader()) + byu[i].SetGeometryFileName(motorFile) + byu[i].SetPartNumber(i + 1) + + normals.append(vtk.vtkPolyDataNormals()) + normals[i].SetInputConnection(byu[i].GetOutputPort()) + + tex.append(vtk.vtkImplicitTextureCoords()) + tex[i].SetInputConnection(normals[i].GetOutputPort()) + tex[i].SetRFunction(planes) + # tex[i].FlipTextureOn() + + byuMapper.append(vtk.vtkDataSetMapper()) + byuMapper[i].SetInputConnection(tex[i].GetOutputPort()) + + byuActor.append(vtk.vtkActor()) + byuActor[i].SetMapper(byuMapper[i]) + byuActor[i].SetTexture(texture) + byuActor[i].GetProperty().SetColor(colors.GetColor3d(partColours[i])) + + ren.AddActor(byuActor[i]) + if displayParts[i]: + byuActor[i].VisibilityOn() + else: + byuActor[i].VisibilityOff() + + ren.SetBackground(colors.GetColor3d('AliceBlue')) + + renWin.SetSize(512, 512) + + camera = vtk.vtkCamera() + camera.SetFocalPoint(0.0286334, 0.0362996, 0.0379685) + camera.SetPosition(1.37067, 1.08629, -1.30349) + camera.SetViewAngle(17.673) + camera.SetClippingRange(1, 10) + camera.SetViewUp(-0.376306, -0.5085, -0.774482) + ren.SetActiveCamera(camera) + + # Render the image. + iren.Initialize() + iren.Start() + + +def get_program_parameters(): + import argparse + description = 'Texture clipping using a transparent texture map.' + epilogue = ''' + Texture clipping using a transparent texture map. + ''' + parser = argparse.ArgumentParser(description=description, epilog=epilogue, + formatter_class=argparse.RawDescriptionHelpFormatter) + parser.add_argument('textureFile', help='The texture file: texThres2.vtk.') + parser.add_argument('motorFile', help='The motor file: motor.g.') + args = parser.parse_args() + return args.textureFile, args.motorFile + + +if __name__ == '__main__': + main()