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.
[…] 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 […]