Closed marcomusy closed 3 months ago
Hi Marco, thanks for looking into it :)
Might be a casting to float32 problem
Seems there is something related to this... Whether it is the casting itself, or VTK's interpretation 🤔 Since I have a few different pointdata arrays in my real data, I thought I'd take a look at what happens to the others and there is indeed some (to me) quite odd behaviour. I adapt your example to show what happens.
Case 1
msh.pointdata["RGBA_TEST"] = arr[:, (0,1,2)].copy()
msh.pointdata["RGBA_TEST2"] = arr[:, (0,1,2)].copy()
msh.pointdata.select("RGBA_TEST2") # select last
Does not work.
Print 1:
vedo.shapes.Grid at (0x1380afff0)
...
pointdata : "RGBA" (uint8), dim=4
pointdata : "RGBA_TEST" (uint8), dim=3
pointdata * : "RGBA_TEST2" (uint8), dim=3
Print 2:
vedo.shapes.Grid at (0x1380afff0)
pointdata ** : "RGBA_TEST2" (float32), dim=3
pointdata : "TextureCoordinates" (float32), dim=2
pointdata : "RGBA" (uint8), dim=4
pointdata : "RGBA_TEST" (uint8), dim=3
N.B., nothing has happened to RGBA_TEST
pointdata, it's still 3D uint8.
Case 2
msh.pointdata["RGBA_TEST"] = arr[:, (0,1,2)].copy()
msh.pointdata["RGBA_TEST2"] = arr[:, (0,1,2)].copy()
msh.pointdata.select("RGBA_TEST") # select any that is not last
This does work.
Print 1:
vedo.shapes.Grid at (0x12ee929c0)
...
pointdata : "RGBA" (uint8), dim=4
pointdata * : "RGBA_TEST" (uint8), dim=3
pointdata ** : "RGBA_TEST2" (uint8), dim=3
Print 2:
vedo.shapes.Grid at (0x12ee929c0)
...
pointdata ** : "RGBA_TEST2" (float32), dim=3
pointdata : "TextureCoordinates" (float32), dim=2
pointdata : "RGBA" (uint8), dim=4
pointdata * : "RGBA_TEST" (uint8), dim=3
After the transform VTK seems to have
So if there's an active 3D (RGB) pointdata, that is not the last-added array in pointdata, everything is fine, but if it's the last one, this bug appears. I think.
Thanks! Indeed what happens is that the vtkTransformFilter
casts uint8 type into float32 only if a dataset has any "active vector" array present.
I think this has to be an unintended behavior in VTK as it makes very little sense to me.... I could only partially fix this in vedo (just pushed to master).
I guess if the mesh position is set before anything related to data arrays all will be working fine.
Thanks :)
I guess if the mesh position is set before anything related to data arrays all will be working fine.
That's working great for me.
Indeed what happens is that the vtkTransformFilter casts uint8 type into float32 only if a dataset has any "active vector" array present. I think this has to be an unintended behavior in VTK as it makes very little sense to me....
Understood, and yes, made little sense to me!
But... After trying a bunch of things, maybe it actually does make some sense?
I've been stuck here thinking about a translation because that's what I'm using; indeed the selected array is cast to float, but the values are equal.
But what about rotation and scaling? If an "active vector" that's actually a vector quantity is assigned to a pointcloud and that pointcloud were to be rotated or scaled, well, then the vectors must be rotated or scaled, hence the cast to float.
And, indeed, they are; if we rotate or scale our image mesh, VTK does indeed "rotate"/"scale" our "vector" (RGB) and we end up with funny colours (after ensuring everything is back in 0-255 range).
BTW since Vedo sets an active vector data on assignment into pointdata, whether or not 'rbg' is in the field name, then your fix in master will deal with that case, but what if a user sets their own vector data? That will be unselected on assign, right? Maybe you are already well aware of this, in which case, sorry 😅
Yes! Makes sense now! The vectors are cast to float to accommodate for transformations, eg:
from vedo import *
plane = Grid()
plane.pointdata["SomeVector"] = np.zeros([plane.npoints, 3]) + [1,0,0]
plane.rotate_x(20).rotate_y(20)
n = plane.pointdata["Normals"] * 0.05
v = plane.pointdata["SomeVector"] * 0.05
arrsn = Arrows(plane.vertices, plane.vertices + n, c='red5')
arrsv = Arrows(plane.vertices, plane.vertices + v, c='blue5')
show(plane, arrsv, arrsn, axes=1)
VTK seems to be reinterpreting/resetting
mapper.SetColorModeToDirectScalars()
after a dataset transformation:print() before
msh.z(-10)
gives:print() after:
Single star = active scalars Double star = active vectors.
needs to be looked at, as there no good reason for this to happen. Might be a casting to float32 problem.
@antmatyjajo