CellTypeSource

VTKExamples/Python/GeometricObjects/CellTypeSource


Description

This example uses vtkCellTypeSource to generate a vtkUnstructuredGrid. If a cell does not fill a rectangular area or volume, then multiple cells will be generated. For example, a vtkTetra requires 12 cells to fill a cube. A vtkTriangle requires two cells to fill a square. vtkCellTypeSource generates a uniform set of coordinates. The example perturbs those coordinates to illustrate the results of the vtkTessellatorFilter. Also, each cell is passed through vtkShrinkFilter to help identify the cells. Each generated cell also has a unique color.

The example takes an optonal argument, a vtkCell name.

For example, to generate vtkTriangles, run

CellTypeSource vtkTriangle

Code

CellTypeSource.py

# !/usr/bin/env python
# -*- coding: utf-8 -*-

import vtk


def main():
    cellName = get_program_parameters()

    # Store the cell class names in a dictionary.
    cellMap = dict()
    cellMap[vtk.vtkCellTypes.GetClassNameFromTypeId(vtk.VTK_LINE)] = vtk.VTK_LINE
    cellMap[vtk.vtkCellTypes.GetClassNameFromTypeId(vtk.VTK_QUADRATIC_EDGE)] = vtk.VTK_QUADRATIC_EDGE
    cellMap[vtk.vtkCellTypes.GetClassNameFromTypeId(vtk.VTK_CUBIC_LINE)] = vtk.VTK_CUBIC_LINE

    cellMap[vtk.vtkCellTypes.GetClassNameFromTypeId(vtk.VTK_TRIANGLE)] = vtk.VTK_TRIANGLE
    cellMap[vtk.vtkCellTypes.GetClassNameFromTypeId(vtk.VTK_QUADRATIC_TRIANGLE)] = vtk.VTK_QUADRATIC_TRIANGLE
    cellMap[vtk.vtkCellTypes.GetClassNameFromTypeId(vtk.VTK_QUAD)] = vtk.VTK_QUAD
    cellMap[vtk.vtkCellTypes.GetClassNameFromTypeId(vtk.VTK_QUADRATIC_QUAD)] = vtk.VTK_QUADRATIC_QUAD

    cellMap[vtk.vtkCellTypes.GetClassNameFromTypeId(vtk.VTK_TETRA)] = vtk.VTK_TETRA
    cellMap[vtk.vtkCellTypes.GetClassNameFromTypeId(vtk.VTK_HEXAHEDRON)] = vtk.VTK_HEXAHEDRON
    cellMap[vtk.vtkCellTypes.GetClassNameFromTypeId(vtk.VTK_WEDGE)] = vtk.VTK_WEDGE
    cellMap[vtk.vtkCellTypes.GetClassNameFromTypeId(vtk.VTK_PYRAMID)] = vtk.VTK_PYRAMID
    cellMap[vtk.vtkCellTypes.GetClassNameFromTypeId(vtk.VTK_QUADRATIC_WEDGE)] = vtk.VTK_QUADRATIC_WEDGE
    cellMap[vtk.vtkCellTypes.GetClassNameFromTypeId(vtk.VTK_QUADRATIC_PYRAMID)] = vtk.VTK_QUADRATIC_PYRAMID
    cellMap[vtk.vtkCellTypes.GetClassNameFromTypeId(vtk.VTK_QUADRATIC_HEXAHEDRON)] = vtk.VTK_QUADRATIC_HEXAHEDRON
    cellMap[vtk.vtkCellTypes.GetClassNameFromTypeId(vtk.VTK_QUADRATIC_TETRA)] = vtk.VTK_QUADRATIC_TETRA

    if cellName not in cellMap:
        print("Cell type ", cellName, " is not supported.")
        return
    source = vtk.vtkCellTypeSource()
    source.SetCellType(cellMap[cellName])
    source.Update()
    print("Cell: ", cellName)

    originalPoints = source.GetOutput().GetPoints()
    points = vtk.vtkPoints()
    points.SetNumberOfPoints(source.GetOutput().GetNumberOfPoints())
    rng = vtk.vtkMinimalStandardRandomSequence()
    rng.SetSeed(5070)  # for testing
    vtk.vtkMath.RandomSeed(5070)  # for testing
    for i in range(0, points.GetNumberOfPoints()):
        perturbation = [0.0] * 3
        for j in range(0, 3):
            rng.Next()
            perturbation[j] = rng.GetRangeValue(-0.1, 0.1)
        currentPoint = [0.0] * 3
        originalPoints.GetPoint(i, currentPoint)
        points.SetPoint(i, currentPoint[0] + perturbation[0],
                        currentPoint[1] + perturbation[1],
                        currentPoint[2] + perturbation[2])
    source.GetOutput().SetPoints(points)

    numCells = source.GetOutput().GetNumberOfCells()
    print("Number of cells: ", numCells)
    idArray = vtk.vtkIntArray()
    idArray.SetNumberOfTuples(numCells)
    for i in range(0, numCells):
        idArray.InsertTuple1(i, i + 1)
    idArray.SetName("Ids")
    source.GetOutput().GetCellData().AddArray(idArray)
    source.GetOutput().GetCellData().SetActiveScalars("Ids")

    shrink = vtk.vtkShrinkFilter()
    shrink.SetInputConnection(source.GetOutputPort())
    shrink.SetShrinkFactor(.8)

    tessellate = vtk.vtkTessellatorFilter()
    tessellate.SetInputConnection(shrink.GetOutputPort())
    tessellate.SetMaximumNumberOfSubdivisions(3)

    # Create a lookup table to map cell data to colors.
    lut = vtk.vtkLookupTable()

    colorSeries = vtk.vtkColorSeries()
    seriesEnum = colorSeries.BREWER_QUALITATIVE_SET3
    colorSeries.SetColorScheme(seriesEnum)
    colorSeries.BuildLookupTable(lut, colorSeries.ORDINAL)

    # Fill in a few known colors, the rest will be generated if needed.
    colors = vtk.vtkNamedColors()

    # Create a mapper and actor.
    mapper = vtk.vtkDataSetMapper()
    mapper.SetInputConnection(source.GetOutputPort())
    mapper.SetInputConnection(shrink.GetOutputPort())
    mapper.SetScalarRange(0, numCells + 1)
    mapper.SetLookupTable(lut)
    mapper.SetScalarModeToUseCellData()
    mapper.SetResolveCoincidentTopologyToPolygonOffset()
    if (source.GetCellType() == vtk.VTK_QUADRATIC_PYRAMID or
            source.GetCellType() == vtk.VTK_QUADRATIC_WEDGE):
        mapper.SetInputConnection(shrink.GetOutputPort())
    else:
        mapper.SetInputConnection(tessellate.GetOutputPort())
    actor = vtk.vtkActor()
    actor.SetMapper(mapper)
    actor.GetProperty().EdgeVisibilityOn()
    #  actor.GetProperty().SetLineWidth(3)

    textProperty = vtk.vtkTextProperty()
    textProperty.SetFontSize(20)
    textProperty.SetJustificationToCentered()
    textProperty.SetColor(colors.GetColor3d("Lamp_Black"))

    textMapper = vtk.vtkTextMapper()
    textMapper.SetInput(cellName)
    textMapper.SetTextProperty(textProperty)

    textActor = vtk.vtkActor2D()
    textActor.SetMapper(textMapper)
    textActor.SetPosition(320, 20)

    # Create a renderer, render window, and interactor.
    renderer = vtk.vtkRenderer()
    renderWindow = vtk.vtkRenderWindow()
    renderWindow.SetWindowName("Cell Type Source")
    renderWindow.AddRenderer(renderer)
    renderWindowInteractor = vtk.vtkRenderWindowInteractor()
    renderWindowInteractor.SetRenderWindow(renderWindow)

    # Add the actors to the scene.
    renderer.AddViewProp(textActor)
    renderer.AddActor(actor)
    renderer.SetBackground(colors.GetColor3d("Silver"))

    renderer.ResetCamera()
    renderer.GetActiveCamera().Azimuth(30)
    renderer.GetActiveCamera().Elevation(30)
    renderer.ResetCameraClippingRange()

    # Render and interact.
    renderWindow.SetSize(640, 480)
    renderWindow.Render()
    renderWindowInteractor.Start()


def get_program_parameters():
    import argparse
    description = 'Cell Type Source.'
    epilogue = '''
    You can supply an optional argument consisting of a vtkCell name e.g: vtkTriangle.
    The default is vtkTetra.
    '''
    parser = argparse.ArgumentParser(description=description, epilog=epilogue,
                                     formatter_class=argparse.RawDescriptionHelpFormatter)
    parser.add_argument('cell_name', nargs='?', const="vtkTetra", default="vtkTetra", type=str, help="The cell name.")
    args = parser.parse_args()
    return args.cell_name


if __name__ == '__main__':
    main()