vtkVolumeMapper类中提供了两种裁剪技术,分别为Cropping和Clipping
按键盘 R 可以进行矩形区域裁剪,再按R返回正常状态
效果
:
#include "InteractorStyle.hpp"
#pragma once
#include"vtkContourFilter.h"
#include"vtkAreaPicker.h"
#include "vtkInteractorStyleRubberBandPick.h"
#include "vtkClipPolyData.h"
#include "vtkSmartPointer.h"
#include "vtkDataSetMapper.h"
#include <vtkImageCast.h>
#include <vtkSmartPointer.h>
#include <vtkMetaImageReader.h>
#include "vtkRenderWindowInteractor.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkMarchingCubes.h"
#include "vtkStripper.h"
#include "vtkActor.h"
#include "vtkPolyDataMapper.h"
#include "vtkSmoothPolyDataFilter.h"
#include "vtkPolyDataNormals.h"
#include "vtkDecimatePro.h"
#include "vtkProperty.h"
#include <vtkInteractorStyleImage.h>
#include "itkImageToVTKImageFilter.h"
#include "itkVTKImageToImageFilter.h"
#include "itkMeanImageFilter.h"
#include <vtkSmartPointer.h>
#include <vtkGPUVolumeRayCastMapper.h>
#include <vtkColorTransferFunction.h>
#include <vtkPiecewiseFunction.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkPlanes.h>
#include <vtkObjectFactory.h>
#include "vtkRendererCollection.h"
#include <vtkPolyDataToImageStencil.h>
#include <vtkImageStencil.h>
#include <vtkPointData.h>
#include <vtkVersion.h>
#include <vtkSmartPointer.h>
#include <vtkPolyData.h>
#include <vtkImageData.h>
#include <vtkSphereSource.h>
#include <vtkMetaImageWriter.h>
#include <vtkPolyDataToImageStencil.h>
#include <vtkImageStencil.h>
#include <vtkPointData.h>
#include <vtkCutter.h>
#include <vtkPlane.h>
#include <vtkStripper.h>
#include <vtkLinearExtrusionFilter.h>
#include <vtkXMLPolyDataWriter.h>
#include <vtkImageData.h>
#include <vtkMetaImageReader.h>
#include <vtkSmartPointer.h>
#include <vtkInteractorStyleImage.h>
#include <vtkRenderer.h>
#include <vtkImageActor.h>
#include <vtkImageMapper3D.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkPolyDataWriter.h>
#include <vtkAlgorithmOutput.h>
#define VTKISRBP_ORIENT 0
#define VTKISRBP_SELECT 1
class InteractorStyle : public vtkInteractorStyleRubberBandPick //重载vtkInteractorStyleRubberBandPick
{
public:
static InteractorStyle* New();
vtkTypeMacro(InteractorStyle, vtkInteractorStyleRubberBandPick);
InteractorStyle()
{
selectedMapper = vtkSmartPointer<vtkDataSetMapper>::New();
selectedActor = vtkSmartPointer<vtkActor>::New();
renderer = vtkSmartPointer<vtkRenderer>::New();
}
virtual void OnLeftButtonUp()//重写左键按下消息
{
// Forward events
vtkInteractorStyleRubberBandPick::OnLeftButtonUp();
if (this->CurrentMode == VTKISRBP_SELECT)
{
vtkPlanes* frustum = static_cast<vtkAreaPicker*>(this->GetInteractor()->GetPicker())->GetFrustum();//获得鼠标框选矩形
vtkClipPolyData *clipper = vtkClipPolyData::New();//裁剪polydata
clipper->SetInputData(this->Data);
clipper->SetClipFunction(frustum);//!!!!很重要的一步,添加自定义隐函数
clipper->GenerateClipScalarsOn();
clipper->GenerateClippedOutputOn();
clipper->SetValue(0.5);
this->selectedMapper->SetInputConnection(clipper->GetOutputPort());
this->selectedMapper->ScalarVisibilityOff();
this->selectedActor->SetMapper(selectedMapper);
this->selectedActor->GetProperty()->SetColor(1.0, 0.0, 0.0); //(R,G,B)
this->selectedActor->GetProperty()->SetRepresentationToWireframe();
// vtkSmartPointer<vtkPolyDataWriter> vtkWriter = vtkSmartPointer<vtkPolyDataWriter>::New();
//vtkWriter->SetInputConnection(clipper->GetOutputPort());
//vtkWriter->SetFileName("D:\\test.vtk");
//vtkWriter->Write();
renderer->SetBackground(0.6, 0.8, 0.8); // Blue
renderer->AddActor(selectedActor);
renderer->SetViewport(0.5, 0, 1, 1);
this->Interactor->GetRenderWindow()->AddRenderer(renderer);
// this->GetInteractor()->GetRenderWindow()->Render();
this->Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->Render();
}
}
vtkSmartPointer<vtkRenderer> renderer;
vtkSmartPointer<vtkPolyData> Data;
vtkSmartPointer<vtkDataSetMapper> selectedMapper;
vtkSmartPointer<vtkActor> selectedActor;
};
vtkStandardNewMacro(InteractorStyle);
int showVTKDataTTT(vtkSmartPointer<vtkDICOMImageReader> vtkData)
{
vtkSmartPointer<vtkContourFilter> m_skinExtractor2 = vtkSmartPointer<vtkContourFilter>::New();//生成等值面/线
m_skinExtractor2->SetInputConnection(vtkData->GetOutputPort());
m_skinExtractor2->SetValue(0, 400);//调整阈值,400以上是骨组织
//进行精简reduce the number of triangles in a mesh
vtkSmartPointer<vtkDecimatePro> deci = vtkSmartPointer<vtkDecimatePro>::New();
deci->SetInputConnection(m_skinExtractor2->GetOutputPort());
deci->SetTargetReduction(0.3);//Specify the desired reduction in the total number of polygons (e.g., if TargetReduction is set to 0.9, this filter will try to reduce the data set to 10% of its original size).
deci->PreserveTopologyOn();//Turn on/off whether to preserve the topology of the original mesh. If on, mesh splitting and hole elimination will not occur. This may limit the maximum reduction that may be achieved.
//设置优化 用拉普拉斯平滑来调整点的位置
vtkSmartPointer<vtkSmoothPolyDataFilter> smoother = vtkSmartPointer<vtkSmoothPolyDataFilter>::New();
smoother->SetInputConnection(deci->GetOutputPort());
smoother->SetNumberOfIterations(50);//Specify the number of iterations for Laplacian smoothing
//计算多边形网格的法线
vtkSmartPointer<vtkPolyDataNormals> normals = vtkSmartPointer<vtkPolyDataNormals>::New();
normals->SetInputConnection(smoother->GetOutputPort());
normals->FlipNormalsOn();
vtkSmartPointer<vtkPolyDataMapper> mapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputConnection(normals->GetOutputPort());
vtkSmartPointer<vtkActor> actor =
vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
actor->GetProperty()->SetColor(1.0, 1.0, 0.0);
actor->GetProperty()->SetRepresentationToWireframe();
vtkSmartPointer<vtkRenderer> renderer =
vtkSmartPointer<vtkRenderer>::New();
vtkSmartPointer<vtkRenderer> renderer2 =
vtkSmartPointer<vtkRenderer>::New();
vtkSmartPointer<vtkRenderWindow> renderWindow =
vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer(renderer);
vtkSmartPointer<vtkAreaPicker> areaPicker = vtkSmartPointer<vtkAreaPicker>::New();
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
renderWindowInteractor->SetRenderWindow(renderWindow);
renderWindowInteractor->SetPicker(areaPicker);
renderWindowInteractor->Initialize();
// Set the custom stype to use for interaction.
vtkSmartPointer<InteractorStyle> style =
vtkSmartPointer<InteractorStyle>::New();
style->Data = normals->GetOutput();
renderWindowInteractor->SetInteractorStyle(style);
renderWindow->SetSize(640, 480);
renderer->AddActor(actor);
renderer->ResetCamera();
renderer->SetViewport(0, 0, 0.5, 1);
renderer->SetBackground(0.5, 0.5, 0.5); // Blue
//renderer->SetBackground(.2, .3, .4);
renderWindow->Render();
renderWindowInteractor->Start();
return EXIT_SUCCESS;
}
注意:
记得添加
vtkSmartPointer<vtkAreaPicker> areaPicker = vtkSmartPointer<vtkAreaPicker>::New();
renderWindowInteractor->SetPicker(areaPicker);