基於VTK的模型構建以後經常需要對模型進行保存,當然我不想保存爲一個二維的圖像格式
因爲那樣重新讀取太過複雜,如果能將之進行保存爲模型類似的格式那麼以後就只需要直接讀取即可。
三維模型格式應該較多,百度、谷歌都沒有找到較多的範例,不過還是有可使用的,這裏只介紹.vtk 格式。
首先介紹一下本文中使用的方法所用到的主要的類:
vtkDataWriter
vtkPolyDataWriter is a source object that writes ASCII or binary polygonal data files in vtk format. See text for format details.
http://www.vtk.org/doc/nightly/html/classvtkPolyDataWriter.html#details
vtkDataReader
http://www.vtk.org/doc/nightly/html/classvtkDataReader.html
具體介紹請看上面鏈接。
整個源代碼如下:
#include "vtkSmartPointer.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkDICOMImageReader.h"
#include "vtkPolyDataWriter.h"
#include "vtkContourFilter.h"
#include "vtkPolyDataReader.h"
#include "vtkPolyDataMapper.h"
#include "vtkCamera.h"
void build3DView()
{
vtkSmartPointer<vtkRenderer> aRenderer =
vtkSmartPointer<vtkRenderer>::New();
vtkSmartPointer<vtkRenderWindow> renWin =
vtkSmartPointer<vtkRenderWindow>::New();
renWin->AddRenderer(aRenderer);
vtkSmartPointer<vtkRenderWindowInteractor> iren =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
iren->SetRenderWindow(renWin);
vtkDICOMImageReader *dicomReader = vtkDICOMImageReader::New();
dicomReader->SetDataByteOrderToLittleEndian();
dicomReader->SetDirectoryName("D:\\dcm\\02");
/* vtkSmartPointer<vtkJPEGReader> dicomReader =
vtkSmartPointer<vtkJPEGReader>::New();
dicomReader->SetFilePrefix("D:\\dcm\\new\\00");
dicomReader->SetFilePattern("%s%d.dcm");
*/
dicomReader->SetDataByteOrderToLittleEndian();
//dicomReader->SetDataSpacing(1, 0.925, 1.2);
dicomReader->SetDataSpacing(1, 1, 1.4);
dicomReader->SetFileNameSliceSpacing(1);
//dicomReader->SetDataExtent(0, 209, 0, 209, 0, 83);
dicomReader->SetDataExtent(0, 209, 0, 209, 0, 29);
dicomReader->Update();
vtkSmartPointer<vtkContourFilter> skinExtractor =
vtkSmartPointer<vtkContourFilter>::New();
skinExtractor->SetInputConnection(dicomReader->GetOutputPort());
skinExtractor->SetValue(0, 100); //值越大,保留的部分越少。
// VTK 保存
vtkSmartPointer<vtkPolyDataWriter> vtkWriter = vtkSmartPointer<vtkPolyDataWriter>::New();
vtkWriter->SetInput(skinExtractor->GetOutput());
vtkWriter->SetFileName("test.vtk");
vtkWriter->Write();
// Render
renWin->Render();
// Initialize the event loop and then start it.
iren->Initialize();
iren->Start();
}
void readVTKFile()
{
vtkSmartPointer<vtkRenderer> aRenderer =
vtkSmartPointer<vtkRenderer>::New();
vtkSmartPointer<vtkRenderWindow> renWin =
vtkSmartPointer<vtkRenderWindow>::New();
renWin->AddRenderer(aRenderer);
vtkSmartPointer<vtkRenderWindowInteractor> iren =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
iren->SetRenderWindow(renWin);
vtkSmartPointer<vtkPolyDataReader> vtkReader = vtkSmartPointer<vtkPolyDataReader>::New();
vtkReader->SetFileName("test.vtk");
vtkSmartPointer<vtkPolyDataMapper> skinMapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
skinMapper->SetInputConnection(vtkReader->GetOutputPort());
skinMapper->ScalarVisibilityOff(); //這樣不會帶顏色
vtkSmartPointer<vtkActor> skin =
vtkSmartPointer<vtkActor>::New();
skin->SetMapper(skinMapper);
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(skin);
aRenderer->SetActiveCamera(aCamera);
aRenderer->ResetCamera ();
aRenderer->SetBackground(.2, .3, .4);
aRenderer->ResetCameraClippingRange ();
renWin->Render();
iren->Initialize();
iren->Start();
}
void main() //PS: 由於本人是使用分開的獨立兩個函數因此需要先調用build函數構建模型待生成了vtk格式文件後再讀取。
{
//build3DView();//讀入序列圖像提取輪廓構建模型並保存
readVTKFile();//讀取文件,讀入以後也需要做構建平面之類的基本工作,以便顯示
}