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 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

You cannot copy content of this page