The vtkCamera object has a front clipping plane and back clipping plane. Users can only see the middle part between the clipping planes.
So we can change the clipping plane's position, clipping range, to get a different 3D scene.
The relevant variable in VTK is double vtkCamera: ClippingRange[2];
.
When we zoom in or zoom out, the position of the camera will change, so the object will disappear temporarily.
//----------------------------------------------------------------------------
// Move the position of the camera along the view plane normal. Moving
// towards the focal point (e.g., > 1) is a dolly-in, moving away
// from the focal point (e.g., < 1) is a dolly-out.
void vtkCamera::Dolly(double amount)
Here are code snippets.
main.cpp
#include <iostream>
#include <vtkSmartPointer.h>
#include <vtkSphereSource.h>
#include <vtkActor.h>
#include <vtkConeSource.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkLight.h>
#include <vtkCamera.h>
#include <vtkActor2D.h>
#include "vtkCustomStyle.h"
using namespace std;
int main()
{
vtkSmartPointer<vtkConeSource> cone =
vtkSmartPointer<vtkConeSource>::New();
vtkSmartPointer<vtkPolyDataMapper> mapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputConnection( cone->GetOutputPort() );
vtkSmartPointer<vtkActor> actor =
vtkSmartPointer<vtkActor>::New();
actor->SetMapper( mapper );
vtkSmartPointer<vtkRenderer> renderer =
vtkSmartPointer<vtkRenderer>::New();
renderer->AddActor(actor);
renderer->SetBackground( 0, 0, 0 );
vtkSmartPointer<vtkRenderWindow> renderWindow =
vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer( renderer );
int depth = renderWindow->GetDepthBufferSize();
//renderWindow->DebugOn();
cout << "depth: " << depth << endl;
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
renderWindowInteractor->SetRenderWindow( renderWindow );
renderer->ResetCamera();
vtkPtr( style, vtkCustomStyle );
style->Setm_Camera( renderer->GetActiveCamera() );
style->Setm_Actor( actor );
style->Setm_RenderWindow( renderWindow );
style->Setm_Render( renderer );
renderWindowInteractor->SetInteractorStyle( style );
renderWindow->Render();
renderWindowInteractor->Start();
return 0;
}
vtkCustomStyle.h
#pragma once
#include <iostream>
#include <vtkSmartPointer.h>
#include <vtkSphereSource.h>
#include <vtkActor.h>
#include <vtkConeSource.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkLight.h>
#include <vtkCamera.h>
#include <vtkAxisActor.h>
#include <vtkActor2D.h>
#include <vtkAxesActor.h>
#include <vtkParametricTorus.h>
#include <vtkCommand.h>
#include <vtkCellPicker.h>
#include <vtkTransform.h>
#include <vtkParametricFunctionSource.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <QString>
#include <QDebug>
#include "tool.h"
#define vtkPtr( var, className ) vtkSmartPointer<className> var = \
vtkSmartPointer<className>::New()
#define CPP_SET_MACRO(name,type) \
void Set##name(type _arg) \
{ \
if (this->name != _arg) \
{ \
this->name = _arg; \
} \
}
class vtkCustomStyle: public vtkInteractorStyleTrackballCamera
{
public:
static vtkCustomStyle *New(){ return new vtkCustomStyle(); }
void OnLeftButtonDown() override;
void OnLeftButtonUp() override;
//virtual void OnMouseMove();
void Rotate() override;
CPP_SET_MACRO( m_Camera, vtkCamera * )
CPP_SET_MACRO( m_Actor, vtkActor * )
CPP_SET_MACRO( m_RenderWindow, vtkRenderWindow * )
CPP_SET_MACRO( m_Render, vtkRenderer * )
protected:
vtkCustomStyle();
~vtkCustomStyle();
double GetLinearValue( const double &A, const double &B, const double &x );
bool m_Pressed;
vtkCamera *m_Camera;
vtkActor *m_Actor;
vtkRenderWindow *m_RenderWindow;
vtkRenderer *m_Render;
};
vtkCustomStyle.cpp
#include "vtkCustomStyle.h"
void vtkCustomStyle::OnLeftButtonDown()
{
m_Pressed = true;
vtkInteractorStyleTrackballCamera::OnLeftButtonDown();
}
void vtkCustomStyle::OnLeftButtonUp()
{
m_Pressed = false;
vtkInteractorStyleTrackballCamera::OnLeftButtonUp();
}
void vtkCustomStyle::Rotate()
{
if( nullptr == m_Actor || nullptr == m_Camera )
{
cout << "here is nullptr\n";
return ;
}
vtkInteractorStyleTrackballCamera::Rotate();
if( m_Pressed )
{
m_Render->ResetCameraClippingRange();
double *ptr = m_Camera->GetClippingRange();
double v1 = GetLinearValue( ptr[0], ptr[1], 0.6 );
double v2 = GetLinearValue( ptr[0], ptr[1], 0.4 );
//m_Camera->SetClippingRange( ptr[0], (ptr[0] + ptr[1]) / 2 );
m_Camera->SetClippingRange( v1, v2 );
m_RenderWindow->Render();
}
}
vtkCustomStyle::vtkCustomStyle()
{
m_Pressed = false;
m_Camera = nullptr;
m_Actor = nullptr;
m_RenderWindow = nullptr;
SetAutoAdjustCameraClippingRange( 0 );
}
vtkCustomStyle::~vtkCustomStyle()
{
}
double vtkCustomStyle::GetLinearValue(const double &A, const double &B, const double &x)
{
return A * x + B *(1 - x);
}
If we just want to clip the front part of the model, we can set the range:
double v1 = GetLinearValue( ptr[0], ptr[1], 0.6 );
double v2 = GetLinearValue( ptr[0], ptr[1], 0 ); // keep farz value