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()
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.
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 and the result would be close to the soccer ball . The distortions are very visual.
So the best solution is actually to create the soccer ball. The you will get the perfect rendering:
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()