BorderWidget
Repository source: BorderWidget
Description¶
This example draws a border around a region selected with the mouse. Note that the default border color is white - so if you have a white background you will not see anything!
Other languages
See (Cxx)
Question
If you have a question about this example, please use the VTK Discourse Forum
Code¶
BorderWidget.py
#!/usr/bin/env python3
from dataclasses import dataclass
from operator import add
# noinspection PyUnresolvedReferences
import vtkmodules.vtkInteractionStyle
# noinspection PyUnresolvedReferences
import vtkmodules.vtkRenderingOpenGL2
from vtkmodules.vtkCommonColor import vtkNamedColors
from vtkmodules.vtkCommonCore import (
vtkLookupTable
)
from vtkmodules.vtkFiltersSources import vtkPlatonicSolidSource
from vtkmodules.vtkInteractionWidgets import (
vtkBorderRepresentation,
vtkBorderWidget
)
from vtkmodules.vtkRenderingCore import (
vtkActor,
vtkPolyDataMapper,
vtkRenderWindow,
vtkRenderWindowInteractor,
vtkRenderer
)
def main():
colors = vtkNamedColors()
lut = get_platonic_lut()
# A renderer, render window and interactor.
ren = vtkRenderer(background=colors.GetColor3d('SteelBlue'))
ren_win = vtkRenderWindow(window_name='BorderWidget')
ren_win.AddRenderer(ren)
iren = vtkRenderWindowInteractor()
iren.render_window = ren_win
platonic_solid = vtkPlatonicSolidSource(solid_type=PlatonicSolidSource.SolidType.VTK_SOLID_DODECAHEDRON)
mapper = vtkPolyDataMapper(lookup_table=lut, scalar_range=(0, 19))
platonic_solid >> mapper
actor = vtkActor(mapper=mapper)
ren.AddActor(actor)
# Create the widget and its representation
rep = vtkBorderRepresentation(proportional_resize=True, show_border=True, border_color=colors.GetColor3d('Yellow'))
widget = vtkBorderWidget(interactor=iren, representation=rep, selectable=False)
widget.AddObserver('EndInteractionEvent', BorderCallback(ren))
ren_win.Render()
ren.active_camera.Elevation(30.0)
ren.active_camera.Azimuth(180.0)
iren.Initialize()
ren_win.Render()
widget.On()
iren.Start()
def get_platonic_lut():
"""
Get a specialised lookup table for the platonic solids.
Since each face of a vtkPlatonicSolidSource has a different
cell scalar, we create a lookup table with a different colour
for each face.
The colors have been carefully chosen so that adjacent cells
are colored distinctly.
:return: The lookup table.
"""
lut = vtkLookupTable(number_of_table_values=20, table_range=(0.0, 19.0))
# lut.SetNumberOfTableValues(20)
# lut.SetTableRange(0.0, 19.0)
lut.Build()
lut.SetTableValue(0, 0.1, 0.1, 0.1)
lut.SetTableValue(1, 0, 0, 1)
lut.SetTableValue(2, 0, 1, 0)
lut.SetTableValue(3, 0, 1, 1)
lut.SetTableValue(4, 1, 0, 0)
lut.SetTableValue(5, 1, 0, 1)
lut.SetTableValue(6, 1, 1, 0)
lut.SetTableValue(7, 0.9, 0.7, 0.9)
lut.SetTableValue(8, 0.5, 0.5, 0.5)
lut.SetTableValue(9, 0.0, 0.0, 0.7)
lut.SetTableValue(10, 0.5, 0.7, 0.5)
lut.SetTableValue(11, 0, 0.7, 0.7)
lut.SetTableValue(12, 0.7, 0, 0)
lut.SetTableValue(13, 0.7, 0, 0.7)
lut.SetTableValue(14, 0.7, 0.7, 0)
lut.SetTableValue(15, 0, 0, 0.4)
lut.SetTableValue(16, 0, 0.4, 0)
lut.SetTableValue(17, 0, 0.4, 0.4)
lut.SetTableValue(18, 0.4, 0, 0)
lut.SetTableValue(19, 0.4, 0, 0.4)
return lut
class BorderCallback(object):
def __init__(self, ren):
self.ren = ren
def __call__(self, caller, ev):
def fmt_floats(v, w=0, d=6, pt='f'):
"""
Pretty print a list or tuple of floats.
:param v: The list or tuple of floats.
:param w: Total width of the field.
:param d: The number of decimal places.
:param pt: The presentation type, 'f', 'g' or 'e'.
:return: A string.
"""
pt = pt.lower()
if pt not in ['f', 'g', 'e']:
pt = 'f'
return ', '.join([f'{element:{w}.{d}{pt}}' for element in v])
# Just do this to demonstrate who called callback and the event that triggered it.
# print(caller.GetClassName(), 'Event Id:', ev)
rep = caller.representation
# Viewport coordinates.
lower_left_vp = rep.position
ur = rep.position2
upper_right_vp = tuple(map(add, lower_left_vp, ur))
print('Viewport coordinates:')
print(f'Lower left: ({lower_left_vp[0]:0.6f}, {lower_left_vp[1]:0.6f}),')
print(f'Upper right: ({fmt_floats(upper_right_vp,0,6)})')
# World coordinates.
lower_left_coordinate = rep.position_coordinate
lower_left = lower_left_coordinate.GetComputedWorldValue(self.ren)
upper_right_coordinate = rep.position2_coordinate
upper_right = upper_right_coordinate.GetComputedWorldValue(self.ren)
print('World coordinates:')
print(f'Lower left: ({fmt_floats(lower_left)})')
print(f'Upper right: ({fmt_floats(upper_right)}),')
@dataclass(frozen=True)
class PlatonicSolidSource:
@dataclass(frozen=True)
class SolidType:
VTK_SOLID_TETRAHEDRON: int = 0
VTK_SOLID_CUBE: int = 1
VTK_SOLID_OCTAHEDRON: int = 2
VTK_SOLID_ICOSAHEDRON: int = 3
VTK_SOLID_DODECAHEDRON: int = 4
if __name__ == '__main__':
main()