So there appears to be an obscure bug present in the vtkCocoa renderer (used in MacOS) which happens in vtkGraphLayoutView. Modifying the line width of the graph edges breaks the render. It appears that all rectangles in the graph layout are typically internally treated as two triangles, but something is wrong with the creation of these objects in cocoa in which only one triangle is created per edge.
The effect is seen in the screenshot below:
In this example there should be 5 edges, which should be internally comprised of 10 triangles. Only 5 triangles are created in the Cocoa version, which are then laid out expecting 10. This breaks a lot of the subsequent code that handles edge selection / picking as triangles are rendered in the wrong positions.
The correct behaviour is shown in the same example running in a non-cocoa renderer, all 5 edges are shown properly.
I’ve written a slightly modified example code to demonstrate the effect, it’ll likely only happen on MacOS.
#!/usr/bin/env python
# noinspection PyUnresolvedReferences
import vtkmodules.vtkInteractionStyle
# noinspection PyUnresolvedReferences
import vtkmodules.vtkRenderingOpenGL2
from vtkmodules.vtkCommonDataModel import (
vtkMutableDirectedGraph,
vtkTree
)
from vtkmodules.vtkViewsInfovis import vtkGraphLayoutView
import vtk
def make_theme(use_mellow=True):
theme = vtk.vtkViewTheme()
if use_mellow:
theme.CreateMellowTheme()
theme.SetLineWidth(45) # this method shows the effect
return theme
else:
theme.SetVertexLabelColor(0,0,0)
theme.SetEdgeLabelColor(0,0,0)
theme.SetPointSize(10)
theme.SetOutlineColor(vtk.vtkNamedColors().GetColor3d('Black'))
theme.SetSelectedCellColor(vtk.vtkNamedColors().GetColor3d('Red'))
theme.SetSelectedPointColor(vtk.vtkNamedColors().GetColor3d('Red'))
theme.SetPointHueRange(0, 1.0)
theme.SetPointSaturationRange(0.0, 1.0)
theme.SetBackgroundColor([0.3,0.3,0.3])
theme.SetBackgroundColor2([0.7,0.7,0.7])
theme.SetLineWidth(45) # this method shows the effect
return theme
def main():
graph = vtkMutableDirectedGraph()
a = graph.AddVertex()
b = graph.AddChild(a)
c = graph.AddChild(a)
d = graph.AddChild(b)
e = graph.AddChild(c)
f = graph.AddChild(c)
vertex_labels = vtk.vtkStringArray()
vertex_labels.SetName('VertexLabel')
vertex_labels.InsertValue(a, 'a')
vertex_labels.InsertValue(b, 'b')
vertex_labels.InsertValue(c, 'c')
vertex_labels.InsertValue(d, 'd')
vertex_labels.InsertValue(e, 'e')
vertex_labels.InsertValue(f, 'f')
graph.GetVertexData().AddArray(vertex_labels)
edge_labels = vtk.vtkStringArray()
edge_labels.SetName('EdgeLabel')
edge_labels.InsertValue(graph.GetEdgeId(a, b), 'a -> b')
edge_labels.InsertValue(graph.GetEdgeId(a, c), 'a -> c')
edge_labels.InsertValue(graph.GetEdgeId(b, d), 'b -> d')
edge_labels.InsertValue(graph.GetEdgeId(c, e), 'c -> e')
edge_labels.InsertValue(graph.GetEdgeId(c, f), 'c -> f')
graph.GetEdgeData().AddArray(edge_labels)
tree = vtkTree()
success = tree.CheckedShallowCopy(graph)
print('Success?', success)
view = vtkGraphLayoutView()
view.SetRepresentationFromInput(tree)
view.SetLayoutStrategyToTree()
theme = make_theme(use_mellow=True)
view.ApplyViewTheme(theme)
view.SetVertexColorArrayName('VertexDegree')
view.SetColorVertices(True)
view.SetVertexLabelArrayName('VertexLabel')
view.SetVertexLabelVisibility(True)
view.SetEdgeLabelArrayName('EdgeLabel')
view.SetEdgeLabelVisibility(True)
view.SetLayoutStrategyToTree()
view.ResetCamera()
view.GetRenderWindow().SetSize(600, 600)
view.GetRenderWindow().SetWindowName('CreateTree')
view.GetRenderWindow().Render()
view.GetInteractor().Initialize()
view.GetInteractor().Start()
if __name__ == '__main__':
main()