import vtk
import numpy as np
from vtk.util import numpy_support

#  create the eight brick corner points
points = vtk.vtkPoints()
points.InsertNextPoint(0.0, 0.0, 0.0)
points.InsertNextPoint(1.0, 0.0, 0.0)
points.InsertNextPoint(1.0, 1.0, 0.0)
points.InsertNextPoint(0.0, 1.0, 0.0)
points.InsertNextPoint(0.0, 0.0, 1.0)
points.InsertNextPoint(1.0, 0.0, 1.0)
points.InsertNextPoint(1.0, 1.0, 1.0)
points.InsertNextPoint(0.0, 1.0, 1.0)

#  create two coincident brick elements
brick1 = vtk.vtkHexahedron()
brick2 = vtk.vtkHexahedron()

for i in range(8):
    brick1.GetPointIds().SetId(i, i)
    brick2.GetPointIds().SetId(i, i)

#  create the unstructured grid
mesh = vtk.vtkUnstructuredGrid()
mesh.SetPoints(points)
mesh.InsertNextCell(brick1.GetCellType(), brick1.GetPointIds())
mesh.InsertNextCell(brick2.GetCellType(), brick2.GetPointIds())

#  assign unique global element ids
globalids = numpy_support.numpy_to_vtk(np.array([1001, 1002], dtype=np.int64))
globalids.SetName("GlobalElementIds")
mesh.GetCellData().SetGlobalIds(globalids)

#  create the mapper
mapper = vtk.vtkDataSetMapper()
mapper.SetInputData(mesh)
mapper.ScalarVisibilityOff()
mapper.SetResolveCoincidentTopologyToPolygonOffset()
mapper.SetRelativeCoincidentTopologyLineOffsetParameters(1,1)
mapper.SetRelativeCoincidentTopologyPolygonOffsetParameters(1,1)
mapper.SetResolveCoincidentTopologyLineOffsetParameters(1,1)
mapper.SetResolveCoincidentTopologyPolygonOffsetParameters(1,1)

#  create the actor
actor = vtk.vtkActor()
actor.SetMapper(mapper)
actor.GetProperty().SetColor(0.7, 0.8, 1.0)
actor.GetProperty().EdgeVisibilityOn()
actor.GetProperty().SetEdgeColor(0.0, 0.0, 0.0)
actor.GetProperty().SetLineWidth(2.0)

#  create the renderer
renderer = vtk.vtkRenderer()
renderer.AddActor(actor)
renderer.SetBackground(0.15, 0.15, 0.15)

#  create the render window
window = vtk.vtkRenderWindow()
window.AddRenderer(renderer)
window.SetSize(800, 600)

#  create the interactor
interactor = vtk.vtkRenderWindowInteractor()
interactor.SetRenderWindow(window)

#  set an isometric view
renderer.ResetCamera()
renderer.GetActiveCamera().Azimuth(30)
renderer.GetActiveCamera().Elevation(25)
renderer.ResetCameraClippingRange()

#  start renderer
window.Render()
interactor.Start()