VTK 任意平面切割体数据(有什么实际用处吗)
这是一个博主的博客,我把它调通以后,实验出来的效果,感觉跟我自己的需求不是很贴合。我想要的是任意手动切割,切割可能是个曲面,所以我把这个调通的先放这,有个思路总是好的。
#include "vtkPlane.h"
#include "vtkProperty.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkContourFilter.h"
#include "vtkSmartPointer.h"
#include "vtkPolyDataNormals.h"
#include "vtkPolyDataMapper.h"
#include "vtkActor.h"
#include "vtkOutlineFilter.h"
#include "vtkStripper.h"
#include "vtkCamera.h"
#include "vtkSmoothPolyDataFilter.h"
#include <vtkImagePlaneWidget.h>
#include <vtkInteractorStyleTrackballActor.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include "vtkActor.h"
#include <vtkSmartPointer.h>
#include <vtkMetaImageReader.h>
using namespace std;
#include "vtkImplicitPlaneWidget.h"
#include "vtkClipPolyData.h"
class BuildVTKWidgetCall : public vtkCommand
{
public:
static BuildVTKWidgetCall *New()
{
return new BuildVTKWidgetCall;
}
public:
virtual void Execute(vtkObject *caller, unsigned long eventId, void *callData)
{
vtkImplicitPlaneWidget *pWidget = reinterpret_cast<vtkImplicitPlaneWidget*>(caller);
if (pWidget)
{
vtkSmartPointer<vtkPlane> planeNew = vtkPlane::New();
pWidget->GetPlane(planeNew);
cliper->SetClipFunction(planeNew);
cliper->Update();
vtkSmartPointer<vtkPolyData> clipedData = vtkPolyData::New();
clipedData->DeepCopy(cliper->GetOutput());
vtkSmartPointer<vtkPolyDataMapper> coneMapper = vtkPolyDataMapper::New();
coneMapper->SetInputData(clipedData);
coneMapper->ScalarVisibilityOff();
actor->SetMapper(coneMapper);
}
}
void setCliper(vtkSmartPointer<vtkClipPolyData> other){cliper = other;}
void setPlane(vtkSmartPointer<vtkPlane> other){pPlane = other;}
void setActor(vtkSmartPointer<vtkActor> other){actor = other;}
private:
vtkSmartPointer<vtkPlane> pPlane;
vtkSmartPointer<vtkActor> actor;
vtkSmartPointer<vtkClipPolyData> cliper;
};
int main()
{
vtkSmartPointer<vtkRenderer> aRenderer =
vtkSmartPointer<vtkRenderer>::New();
aRenderer->SetViewport(0, 0.0, 0.5, 1.0);
vtkSmartPointer<vtkRenderWindow> renWin =
vtkSmartPointer<vtkRenderWindow>::New();
renWin->AddRenderer(aRenderer);
vtkSmartPointer<vtkRenderWindowInteractor> iren =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
iren->SetRenderWindow(renWin);
vtkSmartPointer<vtkMetaImageReader> Reader =vtkSmartPointer<vtkMetaImageReader>::New();
//vtkSmartPointer<vtkNrrdReader> Reader =vtkSmartPointer<vtkNrrdReader>::New();
Reader->SetFileName("/Users/mac/Desktop/end.mhd"/*"/Users/mac/Desktop/Pic13.nrrd"*/); //读血管mhd或者mha文件
Reader->Update();
if (!Reader->GetOutputPort())
{
cout << "open failed" << endl;
}
cout<<"读取数据完成"<<endl;
vtkSmartPointer<vtkContourFilter> skinExtractor =
vtkSmartPointer<vtkContourFilter>::New();
skinExtractor->SetInputConnection(Reader->GetOutputPort());
skinExtractor->SetValue(0, 1); //值越大,保留的部分越少。
/**做平滑处理**/
vtkSmartPointer<vtkSmoothPolyDataFilter> smooth = vtkSmoothPolyDataFilter::New();
smooth->SetInputConnection( skinExtractor->GetOutputPort());
smooth->SetNumberOfIterations( 100 );
//重新计算法向量
vtkSmartPointer<vtkPolyDataNormals> skinNormals =
vtkSmartPointer<vtkPolyDataNormals>::New();
skinNormals->SetInputConnection(smooth->GetOutputPort());
skinNormals->SetFeatureAngle(180);
vtkSmartPointer<vtkStripper> skinStripper = //create triangle strips and/or poly-lines 为了更快的显示速度
vtkSmartPointer<vtkStripper>::New();
skinStripper->SetInputConnection(skinNormals->GetOutputPort());
vtkSmartPointer<vtkPolyDataMapper> skinMapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
skinMapper->SetInputConnection(skinStripper->GetOutputPort());
skinMapper->ScalarVisibilityOff(); //这样不会带颜色
vtkSmartPointer<vtkActor> skin =
vtkSmartPointer<vtkActor>::New();
skin->SetMapper(skinMapper);
vtkSmartPointer<vtkOutlineFilter> outlineData =
vtkSmartPointer<vtkOutlineFilter>::New();
outlineData->SetInputConnection(Reader->GetOutputPort());
vtkSmartPointer<vtkPolyDataMapper> mapOutline =
vtkSmartPointer<vtkPolyDataMapper>::New();
mapOutline->SetInputConnection(outlineData->GetOutputPort());
vtkSmartPointer<vtkActor> outline =
vtkSmartPointer<vtkActor>::New();
outline->SetMapper(mapOutline);
outline->GetProperty()->SetColor(0, 0, 0);
vtkSmartPointer<vtkCamera> aCamera =
vtkSmartPointer<vtkCamera>::New();
aCamera->SetViewUp (0, 0, -1);
aCamera->SetPosition (0, 1, 0);
aCamera->SetFocalPoint (0, 0, 0);
aCamera->ComputeViewPlaneNormal();
aCamera->Azimuth(30.0);
aCamera->Elevation(30.0);
aCamera->Dolly(1.5);
aRenderer->AddActor(outline);
aRenderer->AddActor(skin);
aRenderer->SetActiveCamera(aCamera);
aRenderer->ResetCamera ();
aRenderer->SetBackground(.2, .3, .4);
aRenderer->ResetCameraClippingRange ();
renWin->SetSize(1000, 1000);
vtkSmartPointer<vtkInteractorStyleTrackballCamera> style =
vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
iren->SetInteractorStyle( style );
/////////设置截面
vtkSmartPointer<vtkClipPolyData> cliper = vtkClipPolyData::New();
cliper->SetInputData(skinStripper->GetOutput());
// 此平面box可以通过右键来进行放大缩小处理(只有当鼠标控制区域只有切割体才单一有效)
vtkSmartPointer<vtkImplicitPlaneWidget> implicitPlaneWidget = vtkImplicitPlaneWidget::New();
implicitPlaneWidget->SetInteractor(iren);
implicitPlaneWidget->SetPlaceFactor(1.25);
//initially position the widget
implicitPlaneWidget->SetInputData(skinStripper->GetOutput());
implicitPlaneWidget->PlaceWidget();
//////Render2
vtkSmartPointer<vtkActor> coneSkinActor = vtkActor::New();
coneSkinActor->SetMapper( skinMapper );
vtkSmartPointer<vtkRenderer> rRenderer =
vtkSmartPointer<vtkRenderer>::New();
rRenderer->SetBackground( 0.2, 0.3, 0.5 );
rRenderer->SetViewport(0.5, 0.0, 1.0, 1.0);
rRenderer->AddActor(coneSkinActor);
vtkSmartPointer<BuildVTKWidgetCall> pCall = BuildVTKWidgetCall::New();
pCall->setActor(coneSkinActor);
pCall->setCliper(cliper);
renWin->AddRenderer(rRenderer);
///////
implicitPlaneWidget->AddObserver(vtkCommand::EndInteractionEvent, pCall);
implicitPlaneWidget->On();
// Render
renWin->Render();
// Initialize the event loop and then start it.
iren->Initialize();
iren->Start();
}
原文博客:https://www.cnblogs.com/dawnWind/archive/2013/02/17/3D_07.html