Textured Terrain being inverted

Hello guys,

In my script, I’m applying a texture to a terrain that I’ve created using points. The issue is that when I’ve elevation (z > 0) the texture is flipped by Z as you can see on the attached image (left is the original image and right is the VTK result).

Anyone knows why this is happening and how to fix this?

My script:
Hello guys,

In my script, I’m applying a texture to a terrain that I’ve created using points. The issue is that when I’ve elevation (z > 0) the texture is flipped by Z as you can see on the attached image (left is the original image and right is the VTK result).

Anyone knows why this is happening and how to fix this?

Thank you,
Thiago

My script:

import vtk

image_name = 'C:/VTK/Data/normalMapping.png'

points = vtk.vtkPoints()
points.InsertNextPoint(0,0,0)
points.InsertNextPoint(100,0,0)
points.InsertNextPoint(200,0,0)
points.InsertNextPoint(300,0,0)
points.InsertNextPoint(400,0,0)
points.InsertNextPoint(0,100, 10)
points.InsertNextPoint(100,100,0)
points.InsertNextPoint(200,100,0)
points.InsertNextPoint(300,100,0)
points.InsertNextPoint(400,100,0)
points.InsertNextPoint(0,200,0)
points.InsertNextPoint(100,200,0)
points.InsertNextPoint(200,200,0)
points.InsertNextPoint(300,200,0)
points.InsertNextPoint(400,200,0)
points.InsertNextPoint(0,300, 10)
points.InsertNextPoint(100,300,0)
points.InsertNextPoint(200,300,0)
points.InsertNextPoint(300,300,0)
points.InsertNextPoint(400,300,0)
points.InsertNextPoint(0,400,0)
points.InsertNextPoint(100,400,0)
points.InsertNextPoint(200,400,0)
points.InsertNextPoint(300,400,0)
points.InsertNextPoint(400,400,0)

polydata = vtk.vtkPolyData()
polydata.SetPoints(points)

delny = vtk.vtkDelaunay2D()
delny.SetInputData(polydata)
delny.Update()
delny.SetTolerance(0.01)

tmapper = vtk.vtkTextureMapToPlane()
tmapper.SetInputConnection(delny.GetOutputPort())

xform = vtk.vtkTransformTextureCoords()
xform.SetInputConnection(tmapper.GetOutputPort())
xform.SetScale(1, 1, 1)

mapper = vtk.vtkDataSetMapper()
mapper.SetInputConnection(xform.GetOutputPort())

bmpReader = vtk.vtkPNGReader()
bmpReader.SetFileName(image_name)
bmpReader.Update()

atext = vtk.vtkTexture()
atext.SetInputConnection(bmpReader.GetOutputPort())
atext.InterpolateOn()

actor = vtk.vtkActor()
actor.SetMapper(mapper)
actor.SetTexture(atext)

ren = vtk.vtkRenderer()
renWin = vtk.vtkRenderWindow()
renWin.AddRenderer(ren)
iren = vtk.vtkRenderWindowInteractor()
iren.SetRenderWindow(renWin)

ren.AddActor(actor)
ren.SetBackground(1, 1, 1)
renWin.SetSize(1000, 1000)

iren.Initialize()
renWin.Render()
iren.Start()

You’ll need to set the plane explicitly when using the vtkTextureMapToPlane filter - it chooses an arbitrarily best-fitting plane by default which is likely not what you want in this case.

Experiment with the following methods of the vtkTextureMapToPlane class:

  • SetOrigin
  • SetPoint1
  • SetPoint2

There are some convenience methods in PyVista to make this whole example way easier:

import pyvista as pv
import numpy as np

image_name = 'C:/VTK/Data/normalMapping.png'

points = np.array([[  0.,   0.,   0.],
                 [100.,   0.,   0.],
                 [200.,   0.,   0.],
                 [300.,   0.,   0.],
                 [400.,   0.,   0.],
                 [  0., 100.,  10.],
                 [100., 100.,   0.],
                 [200., 100.,   0.],
                 [300., 100.,   0.],
                 [400., 100.,   0.],
                 [  0., 200.,   0.],
                 [100., 200.,   0.],
                 [200., 200.,   0.],
                 [300., 200.,   0.],
                 [400., 200.,   0.],
                 [  0., 300.,  10.],
                 [100., 300.,   0.],
                 [200., 300.,   0.],
                 [300., 300.,   0.],
                 [400., 300.,   0.],
                 [  0., 400.,   0.],
                 [100., 400.,   0.],
                 [200., 400.,   0.],
                 [300., 400.,   0.],
                 [400., 400.,   0.]])

# Make point cloud
poly = pv.PolyData(points)
# Traingulate the surface
surf = poly.delaunay_2d()
# Read the texture
texture = pv.read_texture(image_name)

# Define your mapping plane
origin = surf.bounds[0], surf.bounds[2], surf.bounds[4]
point_u = surf.bounds[1], surf.bounds[2], surf.bounds[4]
point_v = surf.bounds[0], surf.bounds[3], surf.bounds[4]

# Mapp the texture coordinates
mapped = surf.texture_map_to_plane(origin=origin, point_u=point_u, point_v=point_v)

# Display it from the top down
mapped.plot(texture=texture, cpos='xy')

Note that I took a screenshot of your image so it has some white edges

1 Like

Thank you Bane Sullivan, it works fine!

Also do you know if it is possible to render the texture with a tiled image?

Thank you.