Gouraud or Flat

(Cornelis Bockemühl) #1

Inside a self-written filter (C++) I am applying a “TubeFilter” to some line segments - works fine.

In order to make things perfect, I would like to have some of the tubes appear “round” and others appear “polygonal”. Normally this is achieved by switching shading between “Gouraud” or “Flat”.

Now this is a display property, not normally a job for the geometric part of the code, but still my first attempt was to simply remove the “Normals” attribute from the tube polydata - with the hope that the Gouraud shading would “fail” and leave them polygonal.

No chance - that Gouraud code seems to be too smart! :wink:

Or is there still a way how I can turn the effect locally off? At least I see that the “caps” of the tubes are showing quite “angular” transitions to the “round faces”, so somehow it must be possible!? Or is it just a question of an acute angle that is “seen” and then avoided? Not possible: even triangular “tubes” are still rounded, and their angles are even more acute than with the caps!

Another option would go the other way round, but so far I did not succeed either: If there would be some “Hint” to be put into the servermanager XML, like “shading=flat”, in order to simply turn off the Gouraud shading I would also have half the way already. I would then simply increase the number of faces a bit for the “round” tubes" (8 or 10 instead of normally 6 for “round” tubes): this might also look ok already.

(Michael Migliore) #2

Removing normals using PassArrays filter makes the display of the tube flat for me.
How are you removing the normals?

(Cornelis Bockemühl) #3

Right, the PassArrays filter might be the better option still!

But just realize it might be a bit more complicated anyway, because the setup is the following:

loop over n tube types (with one being round, the others should be angular)
lines set (n)
apply Tube filter
if this is not the round case: remove the “Normals” attribute
(so far I did it with “RemoveArray” from the “CellData” of the polydata object)
append the resulting thing to the output polydata with the vtkAppendPolyData filter

The complication comes from the vtkAppendPolyData filter: the documentataion says that it will bring together also attributes that exist in ALL the input polydata sets (hmm, what else should it do??).

Meaning that I would lose the Normals also for my “round” data set - and the fact that it does not work so far only shows that I did not do the removal correctly yet…

But once I am doing better I will have the next problem!

(Cornelis Bockemühl) #4

Playing with the normals finally did the trick!
However, the Tube filter generates “TubeNormals”, and with the vtkPolyDataNormals filter and edge splitting I can generate “Normals” that will not be “smoothed”, like this (inside a loop that finally puts several such polydata items together, some “rounded”, others not):

        vtkSmartPointer<vtkTubeFilter> tube = vtkSmartPointer<vtkTubeFilter>::New();

            // use the TubeNormals attribute, copy into Normals and make "standard normals"
            vtkPointData* pData = tube->GetOutput()->GetPointData();
            vtkFloatArray* tnArr = vtkFloatArray::SafeDownCast(pData->GetArray("TubeNormals"));
            if(nullptr != tnArr)
                vtkSmartPointer<vtkFloatArray> narr = vtkSmartPointer<vtkFloatArray>::New();

            // calculate normals with splitting, to avoid rounding effect
            vtkSmartPointer<vtkPolyDataNormals> pnorm = vtkSmartPointer<vtkPolyDataNormals>::New();