Commit 08fb8de4 authored by Andrew Maclean's avatar Andrew Maclean
Browse files

Merge branch 'Add-ImplicitPlaneWidget2.y' into 'master'

Adding a Python example of ImplicitPlaneWidget2

See merge request !275
parents 70e8f97f 306986b6
......@@ -26,6 +26,7 @@ public:
{
return new vtkIPWCallback;
}
virtual void Execute(vtkObject* caller, unsigned long, void*)
{
vtkImplicitPlaneWidget2* planeWidget =
......@@ -33,14 +34,14 @@ public:
vtkImplicitPlaneRepresentation* rep =
reinterpret_cast<vtkImplicitPlaneRepresentation*>(
planeWidget->GetRepresentation());
rep->GetPlane(this->Plane);
}
vtkIPWCallback() : Plane(0), Actor(0)
{
rep->GetPlane(this->plane);
}
vtkPlane* Plane;
vtkActor* Actor;
vtkIPWCallback() = default;
vtkPlane* plane{nullptr};
};
} // namespace
int main(int argc, char* argv[])
......@@ -52,7 +53,7 @@ int main(int argc, char* argv[])
vtkNew<vtkXMLPolyDataReader> reader;
// Setup a visualization pipeline
// Setup a visualization pipeline.
vtkNew<vtkPlane> plane;
vtkNew<vtkClipPolyData> clipper;
clipper->SetClipFunction(plane);
......@@ -67,7 +68,7 @@ int main(int argc, char* argv[])
clipper->SetInputConnection(reader->GetOutputPort());
}
// Create a mapper and actor
// Create a mapper and actor.
vtkNew<vtkPolyDataMapper> mapper;
mapper->SetInputConnection(clipper->GetOutputPort());
vtkNew<vtkActor> actor;
......@@ -78,7 +79,7 @@ int main(int argc, char* argv[])
actor->SetBackfaceProperty(backFaces);
// A renderer and render window
// A renderer and render window.
vtkNew<vtkRenderer> renderer;
vtkNew<vtkRenderWindow> renderWindow;
renderWindow->AddRenderer(renderer);
......@@ -87,24 +88,16 @@ int main(int argc, char* argv[])
renderer->AddActor(actor);
renderer->SetBackground(colors->GetColor3d("SlateGray").GetData());
// An interactor
// An interactor.
vtkNew<vtkRenderWindowInteractor> renderWindowInteractor;
renderWindowInteractor->SetRenderWindow(renderWindow);
renderWindow->Render();
renderer->GetActiveCamera()->Azimuth(-60);
renderer->GetActiveCamera()->Elevation(30);
renderer->ResetCamera();
renderer->GetActiveCamera()->Zoom(0.75);
// The callback will do the work
// The callback will do the work.
vtkNew<vtkIPWCallback> myCallback;
myCallback->Plane = plane;
myCallback->Actor = actor;
myCallback->plane = plane;
vtkNew<vtkImplicitPlaneRepresentation> rep;
rep->SetPlaceFactor(1.25); // This must be set prior to placing the widget
rep->SetPlaceFactor(1.25); // This must be set prior to placing the widget.
rep->PlaceWidget(actor->GetBounds());
rep->SetNormal(plane->GetNormal());
......@@ -113,13 +106,17 @@ int main(int argc, char* argv[])
planeWidget->SetRepresentation(rep);
planeWidget->AddObserver(vtkCommand::InteractionEvent, myCallback);
// Render
renderer->GetActiveCamera()->Azimuth(-60);
renderer->GetActiveCamera()->Elevation(30);
renderer->ResetCamera();
renderer->GetActiveCamera()->Zoom(0.75);
// Render and interact.
renderWindowInteractor->Initialize();
renderWindow->Render();
planeWidget->On();
// Begin mouse interaction
// Begin mouse interaction.
renderWindowInteractor->Start();
return EXIT_SUCCESS;
......
......@@ -653,6 +653,7 @@ See [this tutorial](http://www.vtk.org/Wiki/VTK/Tutorials/3DDataTypes) for a bri
[CameraOrientationWidget](/Python/Widgets/CameraOrientationWidget) | Demonstrates a 3D camera orientation widget.
[CompassWidget](/Python/Widgets/CompassWidget) | Draws an interactive compass.
[ContourWidget](/Python/Widgets/ContourWidget) | Draw a contour (line) which can be deformed by the user
[ImplicitPlaneWidget2](/Python/Widgets/ImplicitPlaneWidget2) | Clip polydata with an implicit plane.
[OrientationMarkerWidget](/Python/Widgets/OrientationMarkerWidget) | Draws two cubes. One of them can be clicked to be rotated, and will rotate the second one. The second one has annotations on it, and can also be moved.
[OrientationMarkerWidget1](/Python/Widgets/OrientationMarkerWidget1) | Display a polydata as an orientation icon.
[ScalarBarWidget](/Python/Widgets/ScalarBarWidget) | The ScalarBarWidget displays a scalar bar that is movable and changes orientation automatically when close to the borders of the image. It needs a ScalarBarActor
......
### Description
This example shows how to use the second generation ImplicitPlaneWidget2 to interactively define the clipping plane for a polydata. If no arguments are specified, a vtkSphereSource generates the polydata. By specifying a .vtp file, the example can operate on arbitrary polydata.
For example, try VTKData/Data/cow.vtp.
#!/usr/bin/env python3
from pathlib import Path
# You may need to uncomment one or more of the following imports.
# If vtkRenderWindow is used and you want to use OpenGL,
# you also need the vtkRenderingOpenGL2 module.
# If vtkRenderWindowInteractor is used, uncomment vtkInteractionStyle
# If text rendering is used, uncomment vtkRenderingFreeType.
#
# If using PyCharm, preface each one you select with this line:
# noinspection PyUnresolvedReferences
#
# noinspection PyUnresolvedReferences
import vtkmodules.vtkInteractionStyle
# noinspection PyUnresolvedReferences
# import vtkmodules.vtkRenderingContextOpenGL2
# import vtkmodules.vtkRenderingFreeType
# noinspection PyUnresolvedReferences
import vtkmodules.vtkRenderingOpenGL2
# noinspection PyUnresolvedReferences
import vtkmodules.vtkRenderingUI
from vtkmodules.vtkCommonColor import vtkNamedColors
from vtkmodules.vtkCommonCore import vtkCommand
from vtkmodules.vtkCommonDataModel import vtkPlane
from vtkmodules.vtkFiltersCore import (
vtkClipPolyData
)
from vtkmodules.vtkFiltersSources import vtkSphereSource
from vtkmodules.vtkIOXML import vtkXMLPolyDataReader
from vtkmodules.vtkInteractionWidgets import (
vtkImplicitPlaneRepresentation,
vtkImplicitPlaneWidget2
)
from vtkmodules.vtkRenderingCore import (
vtkActor,
vtkPolyDataMapper,
vtkProperty,
vtkRenderWindow,
vtkRenderWindowInteractor,
vtkRenderer
)
def main(fn):
colors = vtkNamedColors()
sphere_source = vtkSphereSource()
sphere_source.SetRadius(10.0)
fp = None
if fn:
fp = Path(fn)
if not (fp.is_file() and fp.suffix == '.vtp'):
print('Expected an existing file name with extension .vtp:')
print('Got', fp)
return
# Setup a visualization pipeline.
plane = vtkPlane()
clipper = vtkClipPolyData()
clipper.SetClipFunction(plane)
clipper.InsideOutOn()
if fn:
reader = vtkXMLPolyDataReader()
reader.SetFileName(fp)
clipper.SetInputConnection(reader.GetOutputPort())
else:
clipper.SetInputConnection(sphere_source.GetOutputPort())
# Create a mapper and actor.
mapper = vtkPolyDataMapper()
mapper.SetInputConnection(clipper.GetOutputPort())
actor = vtkActor()
actor.SetMapper(mapper)
back_faces = vtkProperty()
back_faces.SetDiffuseColor(colors.GetColor3d('Gold'))
actor.SetBackfaceProperty(back_faces)
# A renderer and render window
renderer = vtkRenderer()
ren_win = vtkRenderWindow()
ren_win.AddRenderer(renderer)
ren_win.SetWindowName('ImplicitPlaneWidget2')
renderer.AddActor(actor)
renderer.SetBackground(colors.GetColor3d('SlateGray'))
# An interactor
iren = vtkRenderWindowInteractor()
iren.SetRenderWindow(ren_win)
# The callback will do the work.
my_callback = IPWCallback(plane)
rep = vtkImplicitPlaneRepresentation()
rep.SetPlaceFactor(1.25) # This must be set prior to placing the widget
rep.PlaceWidget(actor.GetBounds())
rep.SetNormal(plane.GetNormal())
plane_widget = vtkImplicitPlaneWidget2()
plane_widget.SetInteractor(iren)
plane_widget.SetRepresentation(rep)
plane_widget.AddObserver(vtkCommand.InteractionEvent, my_callback)
renderer.GetActiveCamera().Azimuth(-60)
renderer.GetActiveCamera().Elevation(30)
renderer.ResetCamera()
renderer.GetActiveCamera().Zoom(0.75)
# Render and interact.
iren.Initialize()
ren_win.Render()
plane_widget.On()
# Begin mouse interaction.
iren.Start()
class IPWCallback:
def __init__(self, plane):
self.plane = plane
def __call__(self, caller, ev):
rep = caller.GetRepresentation()
rep.GetPlane(self.plane)
def get_program_parameters():
import argparse
description = 'How to use the second generation ImplicitPlaneWidget2 to interactively' \
' define the clipping plane for a polydata.'
epilogue = '''
If no arguments are specified, a vtkSphereSource generates the polydata.
By specifying a .vtp file, the example can operate on arbitrary polydata.
'''
parser = argparse.ArgumentParser(description=description, epilog=epilogue,
formatter_class=argparse.RawTextHelpFormatter)
parser.add_argument('file_name', nargs='?', default=None, help='A VTK Poly Data file e.g. cow.vtp')
args = parser.parse_args()
return args.file_name
if __name__ == '__main__':
file_name = get_program_parameters()
main(file_name)
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment