VTK生成stl
程序员文章站
2022-04-01 08:43:48
...
//读取二维切片数据序列
vtkNew<vtkDICOMImageReader> reader;//建立一个读取对象
// reader->SetDataByteOrderToLittleEndian();
reader->SetDirectoryName("D:/tmp/DD43E1287B1D9A1CA67BCAF80748D5019CB4DAB4/dcm/1"); //设置读取切片数据文件的路径
reader->Update();
float* imagePositionPatient = reader->GetImagePositionPatient();
double origin[3]={0,0,0};
origin[1] = imagePositionPatient[1];
origin[0] = imagePositionPatient[0];
origin[2] = imagePositionPatient[2];
vtkImageData* data = reader->GetOutput();
double spacing[3];
data->GetSpacing(spacing);
data->GetOrigin(origin);
qDebug()<<"Spacing"<<spacing[0]<<spacing[1]<<spacing[2];
qDebug()<<"Origin"<<reader->GetImagePositionPatient()[0]<<origin[1]<<origin[2];
vtkNew<vtkImageFlip> flip;
flip->SetFilteredAxis(1);
flip->SetInputData(data);
flip->Update();
vtkNew<vtkImageFlip> flip2;
flip2->SetFilteredAxis(2);
flip2->SetInputData(flip->GetOutput());
flip2->Update();
vtkNew<vtkImageData> volume ;
volume->DeepCopy(flip2->GetOutput());
vtkNew<vtkMarchingCubes> surface ;
surface->SetInputData(volume);
surface->ComputeNormalsOn();
// surface->SetValue(0, 0);
// surface->SetValue(0, -310);
surface->SetValue(0, -300);
// surface->SetValue(0, -800);
// surface->SetValue(1, 135);
// surface->SetValue(2, 327.5);
vtkNew<vtkPolyDataMapper> mapper;
mapper->SetInputConnection(surface->GetOutputPort());
mapper->ScalarVisibilityOff();
vtkNew<vtkActor> actor;
actor->SetMapper(mapper);
double p[3];
actor->GetPosition(p);
qDebug()<<p[0]<<p[1]<<p[1];
vtkNew<vtkRenderer> renderer;
// 创建一个球体
vtkNew<vtkSphereSource> sphereSource ;
// sphereSource->SetCenter(0.0, 0.0, 0.0); // 设置中心
// sphereSource->SetCenter(4.40748/spacing[0],-213.511/spacing[1],422.797/spacing[2]); // 设置中心
sphereSource->SetCenter(4.40748,512-213.511,422.797); // 设置中心
sphereSource->SetThetaResolution(40);// 设置维度上的分辨率
sphereSource->SetPhiResolution(40);//设置经度上的分辨率
sphereSource->SetRadius(20.0); // 设置半径
// 映射、制图人
vtkNew<vtkPolyDataMapper> mapper1;
mapper1->SetInputConnection(sphereSource->GetOutputPort()); // 设置映射的渲染数据
// 演员
vtkNew<vtkActor> actor1;
actor1->SetMapper(mapper1);
actor1->GetProperty()->SetColor(1.0,0.7,0.2);
actor1->SetPosition(0,0,0);
//
renderer->AddActor(actor);
renderer->AddActor(actor1);
vtkNew<vtkRenderWindow> renderWindow;
renderWindow->AddRenderer(renderer);
vtkNew<vtkRenderWindowInteractor> interactor;
interactor->SetRenderWindow(renderWindow);
renderWindow->Render();
// interactor->Start();
//---------------------------------------------------------------------//
vtkNew<vtkSTLWriter> partW;
vtkNew<vtkAppendPolyData> apd;
vtkSmartPointer<vtkActorCollection> actors = renderer->GetActors();//获取当前RENDER的ACTORS
int iSum = actors->GetNumberOfItems();//获得这个渲染器内拥有的actor的数量
actors->InitTraversal();//初始化访问便利链表,这两句话不可颠倒,初始化后获得的actor总数就不对了
qDebug()<<iSum;
for (int i = 0;i < iSum;i++)
{
vtkSmartPointer<vtkActor> pA = vtkSmartPointer<vtkActor>::New();
pA = actors->GetNextActor();//遍历每一个actor
double* pPos = pA->GetPosition();
pA->SetPosition(pPos[0],pPos[1],pPos[2]);
qDebug()<<pPos[0]<<pPos[1]<<pPos[2];
/*
if (abs(pPos[0]) < ESP && abs(pPos[1]) < ESP && abs(pPos[2]) <ESP)//有没有平移运动
{
vtkSmartPointer<vtkPolyDataMapper> pMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
pMapper= (vtkPolyDataMapper*)pA->GetMapper();
apd->AddInputData(pMapper->GetInput());
continue;
}
*/
vtkPolyDataMapper* pMapper = (vtkPolyDataMapper*)pA->GetMapper();
vtkPolyData* pData = pMapper->GetInput();
vtkPoints* pPoints = pData->GetPoints();
vtkIdType iSumPts = pPoints->GetNumberOfPoints();//获得三角片点集
qDebug()<<iSumPts;
for (int j = 0;j < iSumPts;j++)
{
double tmp[3];
pPoints->GetPoint(j,tmp);
for(int k=0;k<3;k++)
{
tmp[k]+=pPos[k];
}
pPoints->SetPoint(j,tmp);
}
apd->AddInputData(pData);
apd->Update();
}
//vtkSmartPointer<vtkTriangleFilter> triangleFilter = vtkSmartPointer<vtkTriangleFilter>::New();//三角片过滤器
//triangleFilter->SetInputConnection(apd->GetOutputPort());//导入合并后的polydata
partW->SetInputData(apd->GetOutput());//将三角化后的模型数据导入STL输出器中
partW->SetFileName("d:/test.stl");//设置输出文件名称
partW->SetFileTypeToBinary(); //设置输出的STL文件为二进制类型,二进制占用更小的内存
// partW->Write();//写入文件
interactor->Start();