废话不说,直接上代码:
#include "vtkAutoInit.h"
#include "vtkPolyData.h"
#include "vtkProbeFilter.h"
#include "vtkParametricFunctionSource.h"
#include "vtkParametricSpline.h"
#include "vtkDICOMImageReader.h"
#include "vtkPoints.h"
#include "vtkCellArray.h"
#include "vtkWindowLevelLookupTable.h"
#include "vtkActor.h"
#include "vtkCamera.h"
#include "vtkNamedColors.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkImageData.h"
#include "vtkDataSetMapper.h"VTK_MODULE_INIT(vtkRenderingFreeType)
VTK_MODULE_INIT(vtkRenderingOpenGL2);
VTK_MODULE_INIT(vtkInteractionStyle);
VTK_MODULE_INIT(vtkRenderingVolumeOpenGL2);// 由曲线生成曲面vtkPolyData* SweepLine(vtkParametricFunctionSource* line, double direction[3], double distance, int cols)
{int rows = line->GetOutput()->GetNumberOfPoints(); //待生成的surface的行数为曲线上点的个数double spacing = distance / rows; //列方向上的spacingvtkPolyData* surface = vtkPolyData::New();//生成点cols += 1;int numberOfPoints = rows * cols; //surface内点的个数int numberOfPolys = (rows - 1) * (cols - 1);vtkPoints* points = vtkPoints::New();points->Allocate(numberOfPoints);vtkCellArray* polys = vtkCellArray::New();polys->Allocate(numberOfPolys);//生成每行每列的点坐标,double x[] = { 0.0, 0.0, 0.0 };int cnt = 0;for (int row = 0; row < rows; row++){for (int col = 0; col < cols; col++) {double p[3] = { 0.0,0.0,0.0 };line->GetOutput()->GetPoint(row, p);x[0] = p[0] + direction[0] * col * spacing;x[1] = p[1] + direction[1] * col * spacing;x[2] = p[2] + direction[2] * col * spacing;points->InsertPoint(cnt, x);cnt++;}}//生成四边形vtkIdType pts[4] = { 0,0,0,0 };for (int row = 0; row < rows - 1; row++){for (int col = 0; col < cols - 1; col++){pts[0] = col + row * cols;pts[1] = pts[0] + 1;pts[2] = pts[0] + cols + 1;pts[3] = pts[0] + cols;// polys->InsertNextCell(4, pts); //每临近的四个点构成一个单元polys->InsertNextCell(4, pts);}}surface->SetPoints(points);surface->SetPolys(polys);return surface;
}int main(int argc, char* argv[])
{char szInputFile[] = { "D:/imgdata/2013-06-04_dcm" };vtkDICOMImageReader* reader = vtkDICOMImageReader::New();reader->SetDataByteOrderToLittleEndian();reader->SetDirectoryName(szInputFile);reader->Update();int resolution = 100;int extent[2] = { 255, 255 };double thickness = 1.0;double spacing[2] = { 1.0, 1.0 };//自定义折线顶点坐标vtkPoints* points = vtkPoints::New();//(a,b,c,d)其中a表示序号,(b,c,d)表示点的坐标points->InsertPoint(0, 1.0, 0.0, 0.0);points->InsertPoint(1, 200, 100, 0.0);points->InsertPoint(2, 100, 200, 0.0);points->InsertPoint(3, 200, 300, 0.0);//将点插值逆合成一条曲线vtkParametricSpline* spline = vtkParametricSpline::New();spline->SetPoints(points);vtkParametricFunctionSource* splineFilter = vtkParametricFunctionSource::New();splineFilter->SetParametricFunction(spline);splineFilter->Update();//有曲线生成曲面double direction[] = { 0.0, 0.0, 1.0 };int distance = 160;vtkPolyData* surface = SweepLine(splineFilter, direction, distance, resolution);vtkProbeFilter* sampleVolume = vtkProbeFilter::New();//这里只能填1,和0,否则曲面要么是一块,要么什么也没有;sampleVolume->SetInputConnection(1, reader->GetOutputPort());sampleVolume->SetInputData(0, surface);//根据数据源的数据范围设置映射表的窗宽窗位vtkWindowLevelLookupTable* wlLut = vtkWindowLevelLookupTable::New();double range = reader->GetOutput()->GetScalarRange()[1] - reader->GetOutput()->GetScalarRange()[0];double level = (reader->GetOutput()->GetScalarRange()[1] - reader->GetOutput()->GetScalarRange()[0]) / 2;wlLut->SetWindow(range);wlLut->SetLevel(level);//创建映射器和角色vtkDataSetMapper* mapper = vtkDataSetMapper::New();mapper->SetInputConnection(sampleVolume->GetOutputPort());mapper->SetLookupTable(wlLut);mapper->SetScalarRange(0, 255);vtkActor* actor = vtkActor::New();actor->SetMapper(mapper);//创建渲染器,渲染窗口和交互vtkRenderer* ren = vtkRenderer::New();vtkRenderWindow* renWin = vtkRenderWindow::New();renWin->AddRenderer(ren);renWin->SetWindowName("CurvedReformation");vtkRenderWindowInteractor* iren = vtkRenderWindowInteractor::New();iren->SetRenderWindow(renWin);//将角色添加到场景ren->AddActor(actor);vtkNamedColors* colors = vtkNamedColors::New();// ren->SetBackground(colors->GetColor3d("DarkSlateGray"));ren->SetBackground(0.4, 0.4, 0.4);//设置相机以查看图像ren->GetActiveCamera()->SetViewUp(0, 0, 1);ren->GetActiveCamera()->SetPosition(0, 0, 0);ren->GetActiveCamera()->SetFocalPoint(1, 0, 0);ren->ResetCamera();//渲染和交互renWin->Render();iren->Start();return 0;
}
效果: