Gouraud or Flat

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.

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

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!

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();
        tube->SetInputData(generateSampling->GetOutput());
        tube->SetCapping(true);
        tube->SetNumberOfSides(sd);
        tube->SetRadius(std::stod((*it1)[2]));
        tube->SetOutputPointsPrecision(vtkTubeFilter::DOUBLE_PRECISION);
        tube->Update();

        if(rounded)
        {
            // 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();
                narr->DeepCopy(tnArr);
                narr->SetName("Normals");
                pData->AddArray(narr);
                pData->SetNormals(narr);
            }
            pd->DeepCopy(tube->GetOutput());
        }

        else
        {
            // calculate normals with splitting, to avoid rounding effect
            vtkSmartPointer<vtkPolyDataNormals> pnorm = vtkSmartPointer<vtkPolyDataNormals>::New();
            pnorm->SetInputData(tube->GetOutput());
            pnorm->SetSplitting(true);
            pnorm->SetFeatureAngle(10.);
            pnorm->Update();
            pd->DeepCopy(pnorm->GetOutput());
        }