问题,有时我们需要显示某个 Actor 在相机最前面,可以遮盖后面的物体;显示在顶层有点不准确;因为这个还相机位置也有关系;
这里讲三种情况:
1. 设置 Mapper 顶层,尝试了一下,可以用于某些场景;具体原理未看源码;
原理 :设置 vtkPolyData的 point ,line ,polygon 值 //负值会靠近相机,正值会远离相机 初始值就是0.0
显然他只能用于 vtkPolyData 数据;
const double units0 = -66000;
sphereMapper->SetInputData(sphere->GetOutput());
sphereMapper->SetResolveCoincidentTopologyToPolygonOffset();
sphereMapper->SetRelativeCoincidentTopologyLineOffsetParameters(0, units0);
sphereMapper->SetRelativeCoincidentTopologyPolygonOffsetParameters(0, units0);
sphereMapper->SetRelativeCoincidentTopologyPointOffsetParameter(units0);
样例:
#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;
}
2.设置 VTK的图层 0层最低在后面:
RenderWindow 可以设置多个图层,最前面的显示在上面;
volumeRenderer_->SetLayer(0);
tagRenderer_->SetLayer(1);
GetRenderWindow()->SetNumberOfLayers(2);
GetRenderWindow()->AddRenderer(tagRenderer_);
GetRenderWindow()->AddRenderer(volumeRenderer_);
参考资料:
https://blog.csdn.net/lpsl1882/article/details/52107117
尝试后发现并不能实现这的场景;应该可以适应某些场景;
3.设置相机 前后裁剪平面,只有 前后裁剪平面内可见;可见相机的作用;
前后裁剪平面。裁剪平面与投影方向相交,一般与投影方向也是垂直的。裁剪平面主要用于评估Actor与相机距离的远近,只有在前后裁剪平面之间的Actor才是可见的。裁剪平面的位置可以用vtkCamera::SetClippingRange()方法设置。
这里可以看一下 vtkImageView2 源码 UpdateDisplayExtent,怎么设置 某个图层可见:
个面这个我修改了部分代码
vtkCamera *cam = imageViewer->GetRenderer()->GetActiveCamera();
if (cam)
{
double bounds[6];
actor->GetBounds(bounds);
double spos = bounds[2 * 2];
double cpos = cam->GetPosition()[2];
double range = fabs(spos - cpos);
double *spacing = mImageData->GetSpacing();
double avg_spacing =
(spacing[0] + spacing[1] + spacing[2]) / 3.0;
cam->SetClippingRange(
range - avg_spacing * 3.0, range + avg_spacing * 3.0);
}
我最终要实现的是特定 Actor 显示在某个图层的上面,可以需要调整 相机的 SetClippingRange;