python3dvtktexture-mapping

How to visualize a football with python vtk?


I want to create a 3D scene with a football. The following example creates a sphere and applies a football texture (currently just a checkerboard) to it, which is transformed by some spherical projection as shown in the image below.

import vtk

# create a rendering window
ren = vtk.vtkRenderer()
renWin = vtk.vtkRenderWindow()
renWin.AddRenderer(ren)

# create a renderwindowinteractor
iren = vtk.vtkRenderWindowInteractor()
iren.SetRenderWindow(renWin)

# create source
sphereSource = vtk.vtkSphereSource()
sphereSource.SetCenter(-10.0, 0.0, 0.0)
sphereSource.SetRadius(1)
sphereSource.SetPhiResolution(50)
sphereSource.SetThetaResolution(50)

# fancy football texture
reader = vtk.vtkJPEGReader()
reader.SetFileName('football.jpg')   # currently a checkerboard pattern
texture = vtk.vtkTexture()
texture.SetInputConnection(reader.GetOutputPort())
map_to_sphere = vtk.vtkTextureMapToSphere()
map_to_sphere.SetInputConnection(sphereSource.GetOutputPort())
map_to_sphere.PreventSeamOn()

# create mapper
sphereMapper = vtk.vtkPolyDataMapper()
sphereMapper.SetInputConnection(map_to_sphere.GetOutputPort())

# create actor
sphereActor = vtk.vtkActor()
sphereActor.SetMapper(sphereMapper)
sphereActor.SetTexture(texture)

# assign actor to the renderer
ren.AddActor(sphereActor)

# enable user interface interactor
iren.Initialize()
renWin.Render()
iren.Start()

checkerboard texture on sphere

How can I either apply the texture with another projection method or precondition the 2D texture, such that it compensates the transformation? Or is there another solution? The goal is a distribution of equally sized and shaped patches like on a football.


Solution

  • If you want to wrap an image over the sphere, you will need to take care of the distortion the wrapper creates. It is not really practical, since you need to exactly reverse the distortion the mapper will create, and you don't have neither the result, nor the good source. But you can take an image like this enter image description here and the result would be close to the soccer ball enter image description here. The distortions are very visual.

    So the best solution is actually to create the soccer ball. The you will get the perfect rendering: enter image description here

    The code is below (found in VTK test suite):

    #!/usr/bin/env python
    from vtkmodules.vtkCommonCore import (
        vtkFloatArray,
        vtkLookupTable,
        vtkPoints,
    )
    from vtkmodules.vtkCommonDataModel import (
        vtkCellArray,
        vtkPolyData,
    )
    from vtkmodules.vtkFiltersTexture import vtkTextureMapToSphere
    from vtkmodules.vtkIOImage import vtkPNMReader
    from vtkmodules.vtkRenderingCore import (
        vtkActor,
        vtkDataSetMapper,
        vtkRenderWindow,
        vtkRenderWindowInteractor,
        vtkRenderer,
        vtkTexture,
    )
    import vtkmodules.vtkInteractionStyle
    import vtkmodules.vtkRenderingFreeType
    import vtkmodules.vtkRenderingOpenGL2
    from vtkmodules.util.misc import vtkGetDataRoot
    VTK_DATA_ROOT = vtkGetDataRoot()
    
    # Create the RenderWindow, Renderer and both Actors
    #
    ren1 = vtkRenderer()
    renWin = vtkRenderWindow()
    renWin.AddRenderer(ren1)
    iren = vtkRenderWindowInteractor()
    iren.SetRenderWindow(renWin)
    # create a soccer ball
    #
    points = vtkPoints()
    # first point repeated because polygons were 1-offset
    points.InsertNextPoint(0.348012,0,0.93749)
    points.InsertNextPoint(0.348012,0,0.93749)
    points.InsertNextPoint(0.107542,0.330979,0.93749)
    points.InsertNextPoint(-0.281548,0.204556,0.93749)
    points.InsertNextPoint(-0.281548,-0.204556,0.93749)
    points.InsertNextPoint(0.107542,-0.330979,0.93749)
    points.InsertNextPoint(0.694318,0,0.719669)
    points.InsertNextPoint(0.799191,-0.327801,0.502204)
    points.InsertNextPoint(0.965027,-0.20654,0.154057)
    points.InsertNextPoint(0.965027,0.20654,0.154057)
    points.InsertNextPoint(0.799191,0.327801,0.502204)
    points.InsertNextPoint(0.214556,0.660335,0.719669)
    points.InsertNextPoint(0.558721,0.65878,0.502204)
    points.InsertNextPoint(0.494641,0.853971,0.154057)
    points.InsertNextPoint(0.101778,0.981619,0.154057)
    points.InsertNextPoint(-0.0647933,0.861372,0.502204)
    points.InsertNextPoint(-0.561715,0.40811,0.719669)
    points.InsertNextPoint(-0.453883,0.734949,0.502204)
    points.InsertNextPoint(-0.659322,0.734323,0.154057)
    points.InsertNextPoint(-0.902124,0.400134,0.154057)
    points.InsertNextPoint(-0.839236,0.204556,0.502204)
    points.InsertNextPoint(-0.561715,-0.40811,0.719669)
    points.InsertNextPoint(-0.839236,-0.204556,0.502204)
    points.InsertNextPoint(-0.902124,-0.400134,0.154057)
    points.InsertNextPoint(-0.659322,-0.734323,0.154057)
    points.InsertNextPoint(-0.453883,-0.734949,0.502204)
    points.InsertNextPoint(0.214556,-0.660335,0.719669)
    points.InsertNextPoint(-0.0647933,-0.861372,0.502204)
    points.InsertNextPoint(0.101778,-0.981619,0.154057)
    points.InsertNextPoint(0.494641,-0.853971,0.154057)
    points.InsertNextPoint(0.558721,-0.65878,0.502204)
    points.InsertNextPoint(0.902124,0.400134,-0.154057)
    points.InsertNextPoint(0.839236,0.204556,-0.502204)
    points.InsertNextPoint(0.561715,0.40811,-0.719669)
    points.InsertNextPoint(0.453883,0.734949,-0.502204)
    points.InsertNextPoint(0.659322,0.734323,-0.154057)
    points.InsertNextPoint(-0.101778,0.981619,-0.154057)
    points.InsertNextPoint(0.0647933,0.861372,-0.502204)
    points.InsertNextPoint(-0.214556,0.660335,-0.719669)
    points.InsertNextPoint(-0.558721,0.65878,-0.502204)
    points.InsertNextPoint(-0.494641,0.853971,-0.154057)
    points.InsertNextPoint(-0.965027,0.20654,-0.154057)
    points.InsertNextPoint(-0.799191,0.327801,-0.502204)
    points.InsertNextPoint(-0.694318,0,-0.719669)
    points.InsertNextPoint(-0.799191,-0.327801,-0.502204)
    points.InsertNextPoint(-0.965027,-0.20654,-0.154057)
    points.InsertNextPoint(-0.494641,-0.853971,-0.154057)
    points.InsertNextPoint(-0.558721,-0.65878,-0.502204)
    points.InsertNextPoint(-0.214556,-0.660335,-0.719669)
    points.InsertNextPoint(0.0647933,-0.861372,-0.502204)
    points.InsertNextPoint(-0.101778,-0.981619,-0.154057)
    points.InsertNextPoint(0.659322,-0.734323,-0.154057)
    points.InsertNextPoint(0.453883,-0.734949,-0.502204)
    points.InsertNextPoint(0.561715,-0.40811,-0.719669)
    points.InsertNextPoint(0.839236,-0.204556,-0.502204)
    points.InsertNextPoint(0.902124,-0.400134,-0.154057)
    points.InsertNextPoint(0.281548,-0.204556,-0.93749)
    points.InsertNextPoint(-0.107542,-0.330979,-0.93749)
    points.InsertNextPoint(-0.348012,0,-0.93749)
    points.InsertNextPoint(-0.107542,0.330979,-0.93749)
    points.InsertNextPoint(0.281548,0.204556,-0.93749)
    faces = vtkCellArray()
    faces.InsertNextCell(5)
    faces.InsertCellPoint(5)
    faces.InsertCellPoint(4)
    faces.InsertCellPoint(3)
    faces.InsertCellPoint(2)
    faces.InsertCellPoint(1)
    faces.InsertNextCell(5)
    faces.InsertCellPoint(10)
    faces.InsertCellPoint(9)
    faces.InsertCellPoint(8)
    faces.InsertCellPoint(7)
    faces.InsertCellPoint(6)
    faces.InsertNextCell(5)
    faces.InsertCellPoint(15)
    faces.InsertCellPoint(14)
    faces.InsertCellPoint(13)
    faces.InsertCellPoint(12)
    faces.InsertCellPoint(11)
    faces.InsertNextCell(5)
    faces.InsertCellPoint(20)
    faces.InsertCellPoint(19)
    faces.InsertCellPoint(18)
    faces.InsertCellPoint(17)
    faces.InsertCellPoint(16)
    faces.InsertNextCell(5)
    faces.InsertCellPoint(25)
    faces.InsertCellPoint(24)
    faces.InsertCellPoint(23)
    faces.InsertCellPoint(22)
    faces.InsertCellPoint(21)
    faces.InsertNextCell(5)
    faces.InsertCellPoint(30)
    faces.InsertCellPoint(29)
    faces.InsertCellPoint(28)
    faces.InsertCellPoint(27)
    faces.InsertCellPoint(26)
    faces.InsertNextCell(5)
    faces.InsertCellPoint(35)
    faces.InsertCellPoint(34)
    faces.InsertCellPoint(33)
    faces.InsertCellPoint(32)
    faces.InsertCellPoint(31)
    faces.InsertNextCell(5)
    faces.InsertCellPoint(40)
    faces.InsertCellPoint(39)
    faces.InsertCellPoint(38)
    faces.InsertCellPoint(37)
    faces.InsertCellPoint(36)
    faces.InsertNextCell(5)
    faces.InsertCellPoint(45)
    faces.InsertCellPoint(44)
    faces.InsertCellPoint(43)
    faces.InsertCellPoint(42)
    faces.InsertCellPoint(41)
    faces.InsertNextCell(5)
    faces.InsertCellPoint(50)
    faces.InsertCellPoint(49)
    faces.InsertCellPoint(48)
    faces.InsertCellPoint(47)
    faces.InsertCellPoint(46)
    faces.InsertNextCell(5)
    faces.InsertCellPoint(55)
    faces.InsertCellPoint(54)
    faces.InsertCellPoint(53)
    faces.InsertCellPoint(52)
    faces.InsertCellPoint(51)
    faces.InsertNextCell(5)
    faces.InsertCellPoint(60)
    faces.InsertCellPoint(59)
    faces.InsertCellPoint(58)
    faces.InsertCellPoint(57)
    faces.InsertCellPoint(56)
    faces.InsertNextCell(6)
    faces.InsertCellPoint(2)
    faces.InsertCellPoint(11)
    faces.InsertCellPoint(12)
    faces.InsertCellPoint(10)
    faces.InsertCellPoint(6)
    faces.InsertCellPoint(1)
    faces.InsertNextCell(6)
    faces.InsertCellPoint(3)
    faces.InsertCellPoint(16)
    faces.InsertCellPoint(17)
    faces.InsertCellPoint(15)
    faces.InsertCellPoint(11)
    faces.InsertCellPoint(2)
    faces.InsertNextCell(6)
    faces.InsertCellPoint(4)
    faces.InsertCellPoint(21)
    faces.InsertCellPoint(22)
    faces.InsertCellPoint(20)
    faces.InsertCellPoint(16)
    faces.InsertCellPoint(3)
    faces.InsertNextCell(6)
    faces.InsertCellPoint(5)
    faces.InsertCellPoint(26)
    faces.InsertCellPoint(27)
    faces.InsertCellPoint(25)
    faces.InsertCellPoint(21)
    faces.InsertCellPoint(4)
    faces.InsertNextCell(6)
    faces.InsertCellPoint(1)
    faces.InsertCellPoint(6)
    faces.InsertCellPoint(7)
    faces.InsertCellPoint(30)
    faces.InsertCellPoint(26)
    faces.InsertCellPoint(5)
    faces.InsertNextCell(6)
    faces.InsertCellPoint(12)
    faces.InsertCellPoint(13)
    faces.InsertCellPoint(35)
    faces.InsertCellPoint(31)
    faces.InsertCellPoint(9)
    faces.InsertCellPoint(10)
    faces.InsertNextCell(6)
    faces.InsertCellPoint(17)
    faces.InsertCellPoint(18)
    faces.InsertCellPoint(40)
    faces.InsertCellPoint(36)
    faces.InsertCellPoint(14)
    faces.InsertCellPoint(15)
    faces.InsertNextCell(6)
    faces.InsertCellPoint(22)
    faces.InsertCellPoint(23)
    faces.InsertCellPoint(45)
    faces.InsertCellPoint(41)
    faces.InsertCellPoint(19)
    faces.InsertCellPoint(20)
    faces.InsertNextCell(6)
    faces.InsertCellPoint(27)
    faces.InsertCellPoint(28)
    faces.InsertCellPoint(50)
    faces.InsertCellPoint(46)
    faces.InsertCellPoint(24)
    faces.InsertCellPoint(25)
    faces.InsertNextCell(6)
    faces.InsertCellPoint(7)
    faces.InsertCellPoint(8)
    faces.InsertCellPoint(55)
    faces.InsertCellPoint(51)
    faces.InsertCellPoint(29)
    faces.InsertCellPoint(30)
    faces.InsertNextCell(6)
    faces.InsertCellPoint(9)
    faces.InsertCellPoint(31)
    faces.InsertCellPoint(32)
    faces.InsertCellPoint(54)
    faces.InsertCellPoint(55)
    faces.InsertCellPoint(8)
    faces.InsertNextCell(6)
    faces.InsertCellPoint(14)
    faces.InsertCellPoint(36)
    faces.InsertCellPoint(37)
    faces.InsertCellPoint(34)
    faces.InsertCellPoint(35)
    faces.InsertCellPoint(13)
    faces.InsertNextCell(6)
    faces.InsertCellPoint(19)
    faces.InsertCellPoint(41)
    faces.InsertCellPoint(42)
    faces.InsertCellPoint(39)
    faces.InsertCellPoint(40)
    faces.InsertCellPoint(18)
    faces.InsertNextCell(6)
    faces.InsertCellPoint(24)
    faces.InsertCellPoint(46)
    faces.InsertCellPoint(47)
    faces.InsertCellPoint(44)
    faces.InsertCellPoint(45)
    faces.InsertCellPoint(23)
    faces.InsertNextCell(6)
    faces.InsertCellPoint(29)
    faces.InsertCellPoint(51)
    faces.InsertCellPoint(52)
    faces.InsertCellPoint(49)
    faces.InsertCellPoint(50)
    faces.InsertCellPoint(28)
    faces.InsertNextCell(6)
    faces.InsertCellPoint(32)
    faces.InsertCellPoint(33)
    faces.InsertCellPoint(60)
    faces.InsertCellPoint(56)
    faces.InsertCellPoint(53)
    faces.InsertCellPoint(54)
    faces.InsertNextCell(6)
    faces.InsertCellPoint(37)
    faces.InsertCellPoint(38)
    faces.InsertCellPoint(59)
    faces.InsertCellPoint(60)
    faces.InsertCellPoint(33)
    faces.InsertCellPoint(34)
    faces.InsertNextCell(6)
    faces.InsertCellPoint(42)
    faces.InsertCellPoint(43)
    faces.InsertCellPoint(58)
    faces.InsertCellPoint(59)
    faces.InsertCellPoint(38)
    faces.InsertCellPoint(39)
    faces.InsertNextCell(6)
    faces.InsertCellPoint(47)
    faces.InsertCellPoint(48)
    faces.InsertCellPoint(57)
    faces.InsertCellPoint(58)
    faces.InsertCellPoint(43)
    faces.InsertCellPoint(44)
    faces.InsertNextCell(6)
    faces.InsertCellPoint(52)
    faces.InsertCellPoint(53)
    faces.InsertCellPoint(56)
    faces.InsertCellPoint(57)
    faces.InsertCellPoint(48)
    faces.InsertCellPoint(49)
    faceColors = vtkFloatArray()
    faceColors.InsertNextValue(1)
    faceColors.InsertNextValue(1)
    faceColors.InsertNextValue(1)
    faceColors.InsertNextValue(1)
    faceColors.InsertNextValue(1)
    faceColors.InsertNextValue(1)
    faceColors.InsertNextValue(1)
    faceColors.InsertNextValue(1)
    faceColors.InsertNextValue(1)
    faceColors.InsertNextValue(1)
    faceColors.InsertNextValue(1)
    faceColors.InsertNextValue(1)
    faceColors.InsertNextValue(3)
    faceColors.InsertNextValue(3)
    faceColors.InsertNextValue(3)
    faceColors.InsertNextValue(3)
    faceColors.InsertNextValue(2)
    faceColors.InsertNextValue(2)
    faceColors.InsertNextValue(2)
    faceColors.InsertNextValue(2)
    faceColors.InsertNextValue(2)
    faceColors.InsertNextValue(2)
    faceColors.InsertNextValue(2)
    faceColors.InsertNextValue(2)
    faceColors.InsertNextValue(2)
    faceColors.InsertNextValue(2)
    faceColors.InsertNextValue(2)
    faceColors.InsertNextValue(2)
    faceColors.InsertNextValue(2)
    faceColors.InsertNextValue(2)
    faceColors.InsertNextValue(2)
    faceColors.InsertNextValue(2)
    vertexColors = vtkFloatArray()
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    vertexColors.InsertNextValue(2)
    model = vtkPolyData()
    model.SetPolys(faces)
    model.SetPoints(points)
    model.GetCellData().SetScalars(faceColors)
    model.GetPointData().SetScalars(vertexColors)
    ballTC = vtkTextureMapToSphere()
    ballTC.SetInputData(model)
    lut = vtkLookupTable()
    lut.SetNumberOfColors(4)
    lut.SetTableRange(0.0, 3.0)
    lut.Build()
    lut.SetTableValue(0, 0.0, 0.7, 0.0)
    lut.SetTableValue(1, 0.1, 0.1, 0.1)
    lut.SetTableValue(2, 0.05, 0.05, 0.05)
    lut.SetTableValue(3, 0.99, 0.99, 0.99)
    mapper = vtkDataSetMapper()
    mapper.SetInputConnection(ballTC.GetOutputPort())
    mapper.SetScalarModeToUseCellData()
    mapper.SetLookupTable(lut)
    mapper.SetScalarRange(0,2)
    soccerBall = vtkActor()
    soccerBall.SetMapper(mapper)
    # Add the actors to the renderer, set the background and size
    #
    ren1.AddActor(soccerBall)
    ren1.SetBackground(0.3,0.4,0.6)
    renWin.SetSize(300,300)
    ren1.GetActiveCamera().SetPosition(4.19682,4.65178,6.23545)
    ren1.GetActiveCamera().SetFocalPoint(0,0,0)
    ren1.GetActiveCamera().SetViewAngle(21.4286)
    ren1.GetActiveCamera().SetViewUp(0.451577,-0.833646,0.317981)
    # render the image
    #
    cam1 = ren1.GetActiveCamera()
    cam1.Zoom(1.4)
    ren1.ResetCameraClippingRange()
    iren.Initialize()
    
    
    renWin.Render()
    iren.Start()