We can find that vtkOrientedGlyphContourRepresentation supports to set 3D model always above other objects.

    // Create the contour widget
    vtkSmartPointer<vtkContourWidget> contourWidget =
        vtkSmartPointer<vtkContourWidget>::New();

    // Override the default representation for the contour widget to customize its look
    vtkSmartPointer<vtkOrientedGlyphContourRepresentation> contourRepresentation =
        vtkSmartPointer<vtkOrientedGlyphContourRepresentation>::New();
    // ...
    contourWidget->SetRepresentation(contourRepresentation);
    contourRepresentation->SetAlwaysOnTop( true );

I readed the code source of vtkOrientedGlyphContourRepresentation about AlwaysOnTop, and found that there is polygon offset controling object’s z buffer.

void vtkOrientedGlyphContourRepresentation::BuildRepresentation()
{
  // Make sure we are up to date with any changes made in the placer
  this->UpdateContour();

  if (this->AlwaysOnTop)
  {
    // max value 65536 so we subtract 66000 to make sure we are
    // zero or negative
    this->LinesMapper->SetRelativeCoincidentTopologyLineOffsetParameters(0,-66000);
    this->LinesMapper->SetRelativeCoincidentTopologyPolygonOffsetParameters(0,-66000);
    this->LinesMapper->SetRelativeCoincidentTopologyPointOffsetParameter(-66000);

So we can simulate the operation to make a model awalys on the top.
Here is a simple example that a red sphere on the center of a big cone, we can see the sphere no matter how we rotating the scene.

#include <iostream>
#include <vtkSmartPointer.h>
#include <vtkSphereSource.h>
#include <vtkActor.h>
#include <vtkConeSource.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkPolyDataMapper.h>
#include <vtkSphereSource.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkProperty.h>
#include <vtkLineSource.h>

#define vtkSPtr vtkSmartPointer
#define vtkSPtrNew(Var, Type) vtkSPtr<Type> Var = vtkSPtr<Type>::New();

using namespace std;

int main()
{
    vtkSPtrNew( sphere, vtkSphereSource );
    sphere->SetCenter( 0, 0, 0 );
    sphere->SetRadius( 1 );
    sphere->Update();

    vtkSPtrNew( sphereMapper, vtkPolyDataMapper );

    // set mapper to make sphere always on top
    const double units0 = -66000;
    sphereMapper->SetInputData( sphere->GetOutput() );
    sphereMapper->SetResolveCoincidentTopologyToPolygonOffset();
    sphereMapper->SetRelativeCoincidentTopologyLineOffsetParameters(0, units0);
    sphereMapper->SetRelativeCoincidentTopologyPolygonOffsetParameters(0, units0);
    sphereMapper->SetRelativeCoincidentTopologyPointOffsetParameter(units0);

    vtkSPtrNew( sphereActor, vtkActor );
    sphereActor->SetMapper( sphereMapper );
    sphereActor->GetProperty()->SetColor( 1, 0, 0 );

    vtkSPtrNew( cone, vtkConeSource );
    cone->SetRadius( 2 );
    cone->SetHeight( 4 );
    cone->Update();
    vtkSPtrNew( coneMapper, vtkPolyDataMapper );
    coneMapper->SetInputData( cone->GetOutput() );
    vtkSPtrNew( coneActor, vtkActor );
    coneActor->SetMapper( coneMapper );

    vtkSPtrNew( renderer, vtkRenderer );
    renderer->AddActor( coneActor );
    renderer->AddActor( sphereActor );
    renderer->SetBackground( 0, 0, 0 );

    vtkSPtrNew( renderWindow, vtkRenderWindow );
    renderWindow->AddRenderer( renderer );

    vtkSPtrNew( renderWindowInteractor, vtkRenderWindowInteractor );
    renderWindowInteractor->SetRenderWindow( renderWindow );

    renderer->ResetCamera();
    renderWindow->Render();
    renderWindowInteractor->Start();
    return 0;
}

If we set PolygonOffset for all actor’s mappers, which model will be on the top?
The result depends on the order renderer add actors.

    const double units0 = -66000;
    sphereMapper->SetInputData( sphere->GetOutput() );
    sphereMapper->SetResolveCoincidentTopologyToPolygonOffset();
    sphereMapper->SetRelativeCoincidentTopologyLineOffsetParameters(0, units0);
    sphereMapper->SetRelativeCoincidentTopologyPolygonOffsetParameters(0, units0);
    sphereMapper->SetRelativeCoincidentTopologyPointOffsetParameter(units0);
    vtkSPtrNew( sphereActor, vtkActor );
    sphereActor->SetMapper( sphereMapper );

    vtkSPtrNew( coneMapper, vtkPolyDataMapper );
    coneMapper->SetResolveCoincidentTopologyToPolygonOffset();
    coneMapper->SetRelativeCoincidentTopologyLineOffsetParameters(0, units0);
    coneMapper->SetRelativeCoincidentTopologyPolygonOffsetParameters(0, units0);
    coneMapper->SetRelativeCoincidentTopologyPointOffsetParameter(units0);
    coneMapper->SetInputData( cone->GetOutput() );
    vtkSPtrNew( coneActor, vtkActor );
    coneActor->SetMapper( coneMapper );

    vtkSPtrNew( renderer, vtkRenderer );
    renderer->AddActor( sphereActor );
    renderer->AddActor( coneActor );

The cone is above sphere because the coneActor was the last one that put in the renderer.

Categories: VTK

0 0 votes
Article Rating
Subscribe
Notify of
guest

6 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
trackback

[…] a way to keep a few special models awalys on the top layer in 3D scene. The relative post: https://www.weiy.city/2020/03/make-model-always-on-top/. But it will fail to shift polygons, lines, and points sometimes, eg. when we are in the […]

Haisheng
Haisheng
6 months ago

If I still want to keep the occlusion effect at other angles, how should I do it?

Haisheng
Haisheng
6 months ago
Reply to  StephenWei

Because I use vtkContourWidget and vtkOrientedGlyphContourRepresentation to draw area lines on the OBJ model, if I don’t use AlwaysOnTopOn(), some lines will be on the back of the model, but I use AlwaysOnTopOn(), and there is no occlusion effect。I now try to use sampling to increase the number of points, but this leads to lines that are not very smooth

Haisheng Cao
Haisheng Cao
6 months ago
Reply to  StephenWei

Yes, thanks for your reply

Explain Code
: explain the code you input to help you to understand it.

X
6
0
Would love your thoughts, please comment.x
()
x