[vtkusers] Applying a transform to polydata affects lighting... weirdly

David Gobbi david.gobbi at gmail.com
Thu Feb 1 14:23:14 EST 2018

```Hi Ignatio,

The bottom row in a linear transform matrix should always be 0, 0, 0, 1.
A matrix in which any row or column is all zeros is a singular matrix.

When you apply a transformation that flips the data inside-out, the
windings of the polygons and the directions of the normals are reversed.
This is a mathematical fact, so to speak, and is not specific to VTK.
The filter vtkReverseSense can be used to reverse the normals and
the polygon windings in order to make lighting work properly again.

You can check whether a matrix has a flip by computing the determinant.
If the determinant is negative, there is a flip.   If the determinant is
zero,
the matrix is singular and should not be used (the behavior of the VTK
transform filters is pretty much undefined for singular matrices).

The rotation around Z should work fine, so I'm not sure what the problem
is there.  Try again after setting the bottom row of the matrix to 0, 0, 0,
1.

Cheers,
- David

On Thu, Feb 1, 2018 at 12:02 PM, Ignacio Fernández Galván via vtkusers <
vtkusers at vtk.org> wrote:

> If I apply a nontrivial transformation to polydata, the resulting lighting
> is completely different from the original. A python example is worth a
> thousand words:
>
> #================================================
> import vtk
>
> renderer = vtk.vtkRenderer()
> render_window = vtk.vtkRenderWindow()
> interactor = vtk.vtkRenderWindowInteractor()
> interactor.SetInteractorStyle(vtk.vtkInteractorStyleTrackballCamera())
> render_window.SetInteractor(interactor)
> interactor.Initialize()
> renderer.SetBackground(0.2,0.2,0.2)
>
> sphere = vtk.vtkSphereSource()
> sphere.SetThetaResolution(20)
> sphere.SetPhiResolution(20)
>
> transform = vtk.vtkTransform()
> # no-op
> transform.SetMatrix([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0])
> # invert x axis
> transform.SetMatrix([-1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0])
> # invert x and y axes
> transform.SetMatrix([-1,0,0,0,0,-1,0,0,0,0,1,0,0,0,0,0])
> # 90-degree z rotation
> transform.SetMatrix([0,1,0,0,-1,0,0,0,0,0,1,0,0,0,0,0])
>
> t_sphere = vtk.vtkTransformFilter()
> t_sphere.SetTransform(transform)
> t_sphere.SetInputConnection(sphere.GetOutputPort())
>
> sphere_mapper = vtk.vtkPolyDataMapper()
> #sphere_mapper.SetInputConnection(sphere.GetOutputPort())
> sphere_mapper.SetInputConnection(t_sphere.GetOutputPort())
> sphere_actor = vtk.vtkActor()
> sphere_actor.SetMapper(sphere_mapper)
> sphere_actor.GetProperty().SetColor(1,1,1)
>
> renderer.ResetCamera()
> render_window.Render()
> interactor.Start()
> #================================================
>
> Using the first (no-op) transform is fine, of course.
>
> The second just inverts the x axis, and that results in a black sphere.
> Fair enough, I'm "inverting" the object, so maybe it's inside out.
>
> Then I try inverting the y axis too, that should put things back to
> normal. And indeed it does, apparently.
>
> Perhaps what's needed is a proper rotation/shearing, with no reflection
> component. I try the fourth, which is a pretty innocent 90-degree rotation
> around the z axis, no inversion, no deformation. But lo, now the light
> moves with the object!
>
> Am I missing something or doing something wrong? Any fix or workaround?
> This is with with both VTK 5.8.0 and 8.1.0
>
> Thanks,
> Ignacio
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://vtk.org/pipermail/vtkusers/attachments/20180201/778242db/attachment.html>
```