1.体数据,切平面 ,效果如图:
#include "vtkDICOMImageReader.h"
#include "vtkFixedPointVolumeRayCastMapper.h"
#include "vtkColorTransferFunction.h"
#include "vtkPiecewiseFunction.h"
#include "vtkVolumeProperty.h"
#include "vtkVolume.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkImageMapToColors.h"
#include "vtkPolyDataMapper.h"
#include "vtkActor.h"
#include "vtkCutter.h"
#include "vtkPlane.h"
#include "vtkImageActor.h"
#include "vtkImageData.h"
#include "vtkImageCast.h"
#include "vtkPointData.h"
#include "vtkImageShiftScale.h"
#include "vtkPolyDataToImageStencil.h"
#include "vtkImageStencil.h"
#include "vtkLookupTable.h"
#include "vtkImagePlaneWidget.h"
#include "vtkCellArray.h"
#include "vtkType.h"
#include "vtkPlaneWidget.h"
#include "vtkProperty.h"
#include "vtkCommand.h"
#include "vtkProbeFilter.h"
#include "vtkImplicitPlaneWidget.h"
#include "vtkClipPolyData.h"
class vtkWidgetCall : public vtkCommand
{
public:
static vtkWidgetCall *New()
{
return new vtkWidgetCall;
}
public:
virtual void Execute(vtkObject *caller, unsigned long eventId, void *callData)
{
vtkPlaneWidget *pWidget = vtkPlaneWidget::SafeDownCast(caller);
pWidget->GetPlane(pPlane);
}
public:
vtkPlane *pPlane;
};
void main()
{
vtkRenderer *pRender1 = vtkRenderer::New();
vtkRenderer *pRender2 = vtkRenderer::New();
vtkRenderWindow *pWin = vtkRenderWindow::New();
vtkRenderWindowInteractor *pInt = vtkRenderWindowInteractor::New();
pWin->SetSize(600, 600);
pWin->AddRenderer(pRender1);
pWin->AddRenderer(pRender2);
pRender1->SetViewport(0, 0, .5, 1);
pRender2->SetViewport(0.5, 0, 1, 1);
pRender2->SetBackground(.3, .3, .3);
pInt->SetRenderWindow(pWin);
vtkDICOMImageReader* pReader = vtkDICOMImageReader::New();
pReader->SetDirectoryName("D:/data_dcm/dcm");
pReader->SetDataByteOrderToLittleEndian();
pReader->Update(); //读取
double range[2];
pReader->GetOutput()->GetScalarRange(range);
vtkImageShiftScale *m_pShift = vtkImageShiftScale::New();
m_pShift->SetShift(-1.0*range[0]);
m_pShift->SetScale(255.0 / (range[1] - range[0]));
m_pShift->SetOutputScalarTypeToUnsignedChar();
m_pShift->SetInputConnection(pReader->GetOutputPort());
m_pShift->ReleaseDataFlagOff();
m_pShift->Update();
vtkFixedPointVolumeRayCastMapper *pMapper = vtkFixedPointVolumeRayCastMapper::New();
pMapper->SetInputConnection(pReader->GetOutputPort()); //映射:第一步
vtkColorTransferFunction* pColor = vtkColorTransferFunction::New(); //第二步:color
pColor->AddRGBSegment(0, 1, 1, 1, 255, 1, 1, 1);
vtkPiecewiseFunction* pPiceFun = vtkPiecewiseFunction::New();
pPiceFun->AddSegment(0, 0, 3000, 1);//第三步: vtkPiecwise分段
pMapper->SetBlendModeToMaximumIntensity();
vtkVolumeProperty* pProperty = vtkVolumeProperty::New();//设置属性
pProperty->SetColor(pColor);
pProperty->SetScalarOpacity(pPiceFun);
pProperty->SetInterpolationTypeToLinear();
pProperty->ShadeOff();
vtkVolume* pVolume = vtkVolume::New();
pVolume->SetProperty(pProperty);
pVolume->SetMapper(pMapper); //生成体对象
pRender1->AddVolume(pVolume); //增加体数据到渲染器中渲染
vtkPlaneWidget *pWidget = vtkPlaneWidget::New();
pWidget->SetInteractor(pInt);
pWidget->SetInputData(m_pShift->GetOutput());
pWidget->SetResolution(10);
pWidget->GetPlaneProperty()->SetColor(.9, .4, .4);
pWidget->GetHandleProperty()->SetColor(0, .4, .7);
pWidget->GetHandleProperty()->SetLineWidth(1.5);
pWidget->NormalToYAxisOn();
pWidget->SetRepresentationToSurface();
pWidget->SetPlaceFactor(1.0);
pWidget->SetCenter(m_pShift->GetOutput()->GetCenter());
pWidget->PlaceWidget();
pWidget->On();
vtkPlane *pPlane = vtkPlane::New();
pPlane->SetOrigin(pReader->GetOutput()->GetCenter());
pPlane->SetNormal(1, 0, 0);
vtkCutter *pCut = vtkCutter::New();
pCut->SetCutFunction(pPlane);
pCut->SetInputConnection(m_pShift->GetOutputPort());
pCut->Update();
vtkPolyDataMapper *selectMapper = vtkPolyDataMapper::New();
selectMapper->SetInputConnection(pCut->GetOutputPort());
vtkActor *pActor = vtkActor::New();
pActor->SetMapper(selectMapper);
pRender2->AddActor(pActor);
vtkWidgetCall *pCall = vtkWidgetCall::New();
pCall->pPlane = pPlane;
pWidget->AddObserver(vtkCommand::EndInteractionEvent, pCall);
pInt->Initialize();
pInt->Start();
}
不过 这可能不是大概想要的结果。
2.面绘制,体剪切 ,效果如图:
实现:
#include "vtkDICOMImageReader.h"
#include "vtkFixedPointVolumeRayCastMapper.h"
#include "vtkColorTransferFunction.h"
#include "vtkPiecewiseFunction.h"
#include "vtkVolumeProperty.h"
#include "vtkVolume.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkImageMapToColors.h"
#include "vtkPolyDataMapper.h"
#include "vtkActor.h"
#include "vtkCutter.h"
#include "vtkPlane.h"
#include "vtkImageActor.h"
#include "vtkImageData.h"
#include "vtkImageCast.h"
#include "vtkPointData.h"
#include "vtkImageShiftScale.h"
#include "vtkPolyDataToImageStencil.h"
#include "vtkImageStencil.h"
#include "vtkLookupTable.h"
#include "vtkImagePlaneWidget.h"
#include "vtkCellArray.h"
#include "vtkType.h"
#include "vtkPlaneWidget.h"
#include "vtkProperty.h"
#include "vtkCommand.h"
#include "vtkProbeFilter.h"
#include "vtkImplicitPlaneWidget.h"
#include "vtkClipPolyData.h"
#include "vtkSmartVolumeMapper.h"
#include "vtkCamera.h"
#include "vtkMarchingCubes.h"
#include "vtkDataSetMapper.h"
class vtkWidgetCall : public vtkCommand
{
public:
static vtkWidgetCall *New()
{
return new vtkWidgetCall;
}
public:
vtkWidgetCall::vtkWidgetCall()
{
clippingPlane = vtkSmartPointer<vtkPlane>::New();
}
virtual void Execute(vtkObject *caller, unsigned long eventId, void *callData)
{
vtkPlaneWidget *pWidget = vtkPlaneWidget::SafeDownCast(caller);
pWidget->GetPlane(clippingPlane);
m_pMapper->AddClippingPlane(clippingPlane);
m_pMapper->Update();
}
public:
vtkSmartPointer<vtkPlane> clippingPlane;
vtkRenderWindow * m_pRenderWindow;
vtkDataSetMapper* m_pMapper;
};
void main()
{
vtkRenderer *pRender1 = vtkRenderer::New();
vtkRenderer *pRender2 = vtkRenderer::New();
vtkRenderWindow *pWin = vtkRenderWindow::New();
vtkRenderWindowInteractor *pInt = vtkRenderWindowInteractor::New();
pWin->SetSize(600, 600);
pWin->AddRenderer(pRender1);
pWin->AddRenderer(pRender2);
pRender1->SetViewport(0, 0, .5, 1);
pRender2->SetViewport(0.5, 0, 1, 1);
pRender2->SetBackground(.3, .3, .3);
pInt->SetRenderWindow(pWin);
vtkDICOMImageReader* pReader = vtkDICOMImageReader::New();
pReader->SetDirectoryName("D:/receive/dcm");
pReader->Update(); //读取
vtkSmartPointer<vtkMarchingCubes> skinExtractor =
vtkSmartPointer<vtkMarchingCubes>::New();
skinExtractor->SetInputData(pReader->GetOutput());
skinExtractor->SetValue(0, 50);
vtkSmartPointer<vtkDataSetMapper> skinMapper =
vtkSmartPointer<vtkDataSetMapper>::New();
skinMapper->SetInputConnection(skinExtractor->GetOutputPort());
skinMapper->ScalarVisibilityOff();
vtkSmartPointer<vtkActor> skin =
vtkSmartPointer<vtkActor>::New();
skin->SetMapper(skinMapper);
skin->GetProperty()->SetDiffuseColor(1, .49, .25);
vtkSmartPointer<vtkProperty> backProp =
vtkSmartPointer<vtkProperty>::New();
backProp->SetDiffuseColor(0.8900, 0.8100, 0.3400);
skin->SetBackfaceProperty(backProp);
//创建数据的初始视图很方便。的FocalPoint而位置构成一个矢量方向。稍后(ResetCamera()方法)
//这个矢量是用来定位摄像机来查看数据的
//这个方向。
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);
pRender1->AddActor(skin);
pRender1->SetActiveCamera(aCamera);
pRender1->ResetCamera();
aCamera->Dolly(1.5);
pRender1->SetBackground(.2, .3, .4);
pRender1->ResetCameraClippingRange();
pRender1->ResetCamera();
pWin->Modified();
pWin->Render();
/*Clipping Plane Widget*/
vtkSmartPointer<vtkPlaneWidget> m_pPlaneWidget = vtkSmartPointer<vtkPlaneWidget>::New();
m_pPlaneWidget->SetInteractor(pInt);//与交互器关联
m_pPlaneWidget->SetInputData(pReader->GetOutput());//设置数据集,用于初始化平面,可以不设置
m_pPlaneWidget->SetResolution(50);//即:设置网格数
m_pPlaneWidget->GetPlaneProperty()->SetColor(.2, .8, 0.1);//设置颜色
m_pPlaneWidget->GetPlaneProperty()->SetOpacity(0.5);//设置透明度
m_pPlaneWidget->GetHandleProperty()->SetColor(0, .4, .7);//设置平面顶点颜色
m_pPlaneWidget->GetHandleProperty()->SetLineWidth(1.5);//设置平面线宽
m_pPlaneWidget->NormalToZAxisOn();//初始法线方向平行于Z轴
m_pPlaneWidget->SetRepresentationToWireframe();//平面显示为网格属性
m_pPlaneWidget->SetCenter(skin->GetCenter());//设置平面坐标
m_pPlaneWidget->SetPlaceFactor(1.0);
m_pPlaneWidget->PlaceWidget();//放置平面
m_pPlaneWidget->On();//显示平面
vtkWidgetCall *pCall = vtkWidgetCall::New();
pCall->m_pMapper = skinMapper;
pCall->m_pRenderWindow = pWin;
m_pPlaneWidget->AddObserver(vtkCommand::EndInteractionEvent, pCall);
pInt->Initialize();
pInt->Start();
}
参考:
https://blog.51cto.com/2845385/1021045