ColoredAnnotatedCube
Repository source: ColoredAnnotatedCube
Description¶
This example demonstrates how to color the individual faces of an annotated cube.
This is based on a very nice example by Rodrigo Figueiredo in this discussion.
The process is:
- Create the annotated cube actor using vtkAnnotatedCubeActor.
- Select the names on the faces, text colors and, if needed, any rotations of the text.
- Make the annotated cube transparent.
- Create a cube actor with colored faces.
- Combine the annotated cube actor and cube actor into a prop assembly using vtkPropAssembly. Since the annotated cube and the cube are the same size you get an assembly with colored cube faces and the requisite text.
- Create a vtkOrientationMarkerWidget and set the orientation marker to be the prop assembly.
The function make_annotated_cube_actor
generates the annotated cube with different colored faces which is then added to a vtkOrientationMarkerWidget.
The colored annotated cube is then placed in the lower left of the view (default). Additionally, a vtkOrientationMarkerWidget containing an axes actor has been added to the lower right of the view.
Question
If you have a question about this example, please use the VTK Discourse Forum
Code¶
ColoredAnnotatedCube.py
#!/usr/bin/env python3
from dataclasses import dataclass
# noinspection PyUnresolvedReferences
import vtkmodules.vtkInteractionStyle
# noinspection PyUnresolvedReferences
import vtkmodules.vtkRenderingOpenGL2
from vtkmodules.vtkCommonColor import (
vtkColorSeries,
vtkNamedColors
)
from vtkmodules.vtkCommonCore import (
vtkLookupTable,
vtkUnsignedCharArray
)
from vtkmodules.vtkCommonTransforms import vtkTransform
from vtkmodules.vtkFiltersCore import vtkElevationFilter
from vtkmodules.vtkFiltersGeneral import vtkTransformPolyDataFilter
from vtkmodules.vtkFiltersModeling import vtkBandedPolyDataContourFilter
from vtkmodules.vtkFiltersSources import (
vtkConeSource,
vtkCubeSource
)
from vtkmodules.vtkInteractionStyle import vtkInteractorStyleTrackballCamera
from vtkmodules.vtkInteractionWidgets import vtkOrientationMarkerWidget
from vtkmodules.vtkRenderingAnnotation import (
vtkAnnotatedCubeActor,
vtkAxesActor
)
from vtkmodules.vtkRenderingCore import (
vtkActor,
vtkPolyDataMapper,
vtkPropAssembly,
vtkRenderWindow,
vtkRenderWindowInteractor,
vtkRenderer,
vtkViewport
)
def main():
colors = vtkNamedColors()
# Basic stuff setup
# Set up the renderer, window, and interactor
# Try different gradient modes for the renderer.
# Choose from:
# vtkViewport.GradientModes.VTK_GRADIENT_RADIAL_VIEWPORT_FARTHEST_SIDE,
# vtkViewport.GradientModes.VTK_GRADIENT_RADIAL_VIEWPORT_FARTHEST_CORNER,
# vtkViewport.GradientModes.VTK_GRADIENT_VERTICAL,
# vtkViewport.GradientModes.VTK_GRADIENT_HORIZONTAL,
ren = vtkRenderer(gradient_background=True,
gradient_mode=vtkViewport.GradientModes.VTK_GRADIENT_RADIAL_VIEWPORT_FARTHEST_CORNER,
background=colors.GetColor3d('MistyRose'), background2=colors.GetColor3d('RoyalBlue'))
ren_win = vtkRenderWindow(size=(600, 600), window_name='ColoredAnnotatedCube')
ren_win.AddRenderer(ren)
iren = vtkRenderWindowInteractor()
iren.render_window = ren_win
style = vtkInteractorStyleTrackballCamera()
iren.interactor_style = style
# Create a cone with an elliptical base whose major axis is in th X-direction.
cone_source = vtkConeSource(center=(0.0, 0.0, 0.0), radius=5.0, height=15.0, direction=(0, 1, 0), resolution=60)
transform = vtkTransform()
transform.Scale(1.0, 1.0, 0.75)
trans_f = vtkTransformPolyDataFilter(transform=transform)
cone_source >> trans_f
bounds = trans_f.output.bounds
elevation = vtkElevationFilter(low_point=(0, bounds[2], 0), high_point=(0, bounds[3], 0))
banded_contours = vtkBandedPolyDataContourFilter(
scalar_mode=BandedPolyDataContourFilter.ScalarMode.VTK_SCALAR_MODE_VALUE,
generate_contour_edges=True
)
banded_contours.GenerateValues(11, elevation.GetScalarRange())
# Make a lookup table using a color series.
color_series = vtkColorSeries()
color_series.SetColorScheme(vtkColorSeries.BREWER_DIVERGING_SPECTRAL_11)
lut = vtkLookupTable()
color_series.BuildLookupTable(lut, vtkColorSeries.ORDINAL)
cone_mapper = vtkPolyDataMapper(lookup_table=lut, scalar_range=elevation.scalar_range)
trans_f >> elevation >> banded_contours >> cone_mapper
cone_actor = vtkActor(mapper=cone_mapper)
# Contouring
contour_line_mapper = vtkPolyDataMapper(
scalar_range=elevation.scalar_range,
resolve_coincident_topology=Mapper.ResolveCoincidentTopology.VTK_RESOLVE_POLYGON_OFFSET
)
contour_line_mapper.SetInputData(banded_contours.GetContourEdgesOutput())
contour_line_actor = vtkActor(mapper=contour_line_mapper)
contour_line_actor.property.color = colors.GetColor3d('DimGray')
# Set up the Orientation Marker Widget.
prop_assembly = make_annotated_cube_actor()
om1 = vtkOrientationMarkerWidget(orientation_marker=prop_assembly,
interactor=iren, default_renderer=ren, enabled=True, interactive=True
)
xyz_labels = ['X', 'Y', 'Z']
scale = [1.0, 1.0, 1.0]
total_length = [1.0, 1.0, 1.0]
axes = make_axes_actor(scale, total_length, xyz_labels)
om2 = vtkOrientationMarkerWidget(orientation_marker=axes, viewport=(0.8, 0, 1.0, 0.2),
interactor=iren, default_renderer=ren, enabled=True, interactive=True
)
ren.AddActor(cone_actor)
ren.AddActor(contour_line_actor)
ren.active_camera.Azimuth(45)
ren.active_camera.Pitch(-22.5)
ren.ResetCamera()
ren_win.Render()
iren.Start()
def make_annotated_cube_actor():
annotated_cube = vtkAnnotatedCubeActor(face_text_scale=1.0 / 3.0,
x_plus_face_text='X+', x_minus_face_text='X-',
y_plus_face_text='Y+', y_minus_face_text='Y-',
z_plus_face_text='Z+', z_minus_face_text='Z-'
)
colors = vtkNamedColors()
# Change the vector text colors.
annotated_cube.text_edges_property.color = colors.GetColor3d('Black')
annotated_cube.text_edges_property.line_width = 1
annotated_cube.x_plus_face_property.color = colors.GetColor3d('Turquoise')
annotated_cube.x_minus_face_property.color = colors.GetColor3d('Turquoise')
annotated_cube.y_plus_face_property.color = colors.GetColor3d('Mint')
annotated_cube.y_minus_face_property.color = colors.GetColor3d('Mint')
annotated_cube.z_plus_face_property.color = colors.GetColor3d('Tomato')
annotated_cube.z_minus_face_property.color = colors.GetColor3d('Tomato')
annotated_cube.x_face_text_rotation = 90
annotated_cube.y_face_text_rotation = 180
annotated_cube.z_face_text_rotation = -90
# Make the annotated cube transparent.
annotated_cube.cube_property.opacity = 0
# Colored faces for the cube.
face_colors = vtkUnsignedCharArray()
face_colors.SetNumberOfComponents(3)
face_x_plus = colors.GetColor3ub('Red')
face_x_minus = colors.GetColor3ub('Green')
face_y_plus = colors.GetColor3ub('Blue')
face_y_minus = colors.GetColor3ub('Yellow')
face_z_plus = colors.GetColor3ub('Cyan')
face_z_minus = colors.GetColor3ub('Magenta')
face_colors.InsertNextTypedTuple(face_x_minus)
face_colors.InsertNextTypedTuple(face_x_plus)
face_colors.InsertNextTypedTuple(face_y_minus)
face_colors.InsertNextTypedTuple(face_y_plus)
face_colors.InsertNextTypedTuple(face_z_minus)
face_colors.InsertNextTypedTuple(face_z_plus)
cube_source = vtkCubeSource()
cube_source.update()
cube_source.output.cell_data.SetScalars(face_colors)
cube_mapper = vtkPolyDataMapper()
cube_source >> cube_mapper
cube_actor = vtkActor(mapper=cube_mapper)
# Assemble the colored cube and annotated cube texts into a composite prop.
prop_assembly = vtkPropAssembly()
prop_assembly.AddPart(annotated_cube)
prop_assembly.AddPart(cube_actor)
return prop_assembly
def make_axes_actor(scale, total_length, xyz_labels):
axes = vtkAxesActor(shaft_type=vtkAxesActor.CYLINDER_SHAFT, tip_type=vtkAxesActor.CONE_TIP,
x_axis_label_text=xyz_labels[0], y_axis_label_text=xyz_labels[1],
z_axis_label_text=xyz_labels[2],
scale=scale,
total_length=total_length)
axes.cylinder_radius = 0.5 * axes.cylinder_radius
axes.cone_radius = 1.025 * axes.cone_radius
axes.sphere_radius = 1.5 * axes.sphere_radius
# Set the font properties.
tprop = axes.x_axis_caption_actor2d.caption_text_property
tprop.italic = True
tprop.shadow = True
tprop.SetFontFamilyToTimes()
# Use the same text properties on the other two axes.
axes.y_axis_caption_actor2d.caption_text_property.ShallowCopy(tprop)
axes.z_axis_caption_actor2d.caption_text_property.ShallowCopy(tprop)
# Now color the labels.
colors = vtkNamedColors()
axes.x_axis_caption_actor2d.caption_text_property.color = colors.GetColor3d('FireBrick')
axes.y_axis_caption_actor2d.caption_text_property.color = colors.GetColor3d('DarkGreen')
axes.z_axis_caption_actor2d.caption_text_property.color = colors.GetColor3d('DarkBlue')
return axes
@dataclass(frozen=True)
class BandedPolyDataContourFilter:
@dataclass(frozen=True)
class ScalarMode:
VTK_SCALAR_MODE_INDEX: int = 0
VTK_SCALAR_MODE_VALUE: int = 1
@dataclass(frozen=True)
class Mapper:
@dataclass(frozen=True)
class ColorMode:
VTK_COLOR_MODE_DEFAULT: int = 0
VTK_COLOR_MODE_MAP_SCALARS: int = 1
VTK_COLOR_MODE_DIRECT_SCALARS: int = 2
@dataclass(frozen=True)
class ResolveCoincidentTopology:
VTK_RESOLVE_OFF: int = 0
VTK_RESOLVE_POLYGON_OFFSET: int = 1
VTK_RESOLVE_SHIFT_ZBUFFER: int = 2
@dataclass(frozen=True)
class ScalarMode:
VTK_SCALAR_MODE_DEFAULT: int = 0
VTK_SCALAR_MODE_USE_POINT_DATA: int = 1
VTK_SCALAR_MODE_USE_CELL_DATA: int = 2
VTK_SCALAR_MODE_USE_POINT_FIELD_DATA: int = 3
VTK_SCALAR_MODE_USE_CELL_FIELD_DATA: int = 4
VTK_SCALAR_MODE_USE_FIELD_DATA: int = 5
if __name__ == '__main__':
main()