(接上文)使用VTK中的移动立方体(MC)算法对多个等值面提取。

int maxPointsX, maxPointsY, maxPointsZ;
	std::vector<int> datas;
	std::set<int> values = {1,2};
	const int material_size = values.size();
	readFile(datas, maxPointsZ, maxPointsY, maxPointsX);

	std::vector<vtkSmartPointer<vtkImageData>> imageDatas;
	std::vector<unsigned char*> voxelDatas;
	voxelDatas.resize(material_size);
	imageDatas.resize(material_size);
	for (int i = 0; i < material_size; i++)
	{
		vtkSmartPointer<vtkImageData> imageData = vtkSmartPointer<vtkImageData>::New();
		imageData->SetDimensions(maxPointsX + 2, maxPointsY + 2, maxPointsZ + 2);//设置网格的尺寸
		imageData->AllocateScalars(VTK_UNSIGNED_CHAR, 1);
		imageData->SetSpacing(1.0, 1.0, 1.0);
		unsigned char* voxelData = static_cast<unsigned char*>(imageData->GetScalarPointer());
		voxelDatas[i] = voxelData;
		imageDatas[i] = imageData;
	}

	int k = 0;
	int count = 0;
	for (int i = -1; i <= maxPointsZ; ++i) {
		for (int j = -1; j <= maxPointsY; ++j) {
			for (int l = -1; l <= maxPointsX; ++l) {
				if (i == -1 || i == maxPointsZ || j == -1 || j == maxPointsY || l == -1 || l == maxPointsX) {
					voxelDatas[0][k] = 0;
					voxelDatas[1][k] = 0;
				}
				else {
					if (datas[count] == 0) {
						voxelDatas[0][k] = 0;
						voxelDatas[1][k] = 0;
					}
					else if (datas[count] == 1) {
						voxelDatas[0][k] = 1;
						voxelDatas[1][k] = 0;
					}
					else{
						voxelDatas[0][k] = 0;
						voxelDatas[1][k] = 2;
					}
					count++;
				}
				k++;
			}
		}
	}
	vector<vtkSmartPointer<vtkActor>> actors;
	for (int i = 0; i < material_size; i++) {
		vtkSmartPointer<vtkMarchingCubes> marchingCubes = vtkSmartPointer<vtkMarchingCubes>::New();
		marchingCubes->SetInputData(imageDatas[i]);
		marchingCubes->SetValue(0, i + 1);
		marchingCubes->Update();

		vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
		mapper->SetInputConnection(marchingCubes->GetOutputPort());
		mapper->ScalarVisibilityOff();

		vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
		actor->SetMapper(mapper);
		actor->GetProperty()->SetColor(&colors[i * 3]);
		actors.push_back(actor);
	}
	
	vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
	for (vtkSmartPointer<vtkActor> actor : actors)
	{
		renderer->AddActor(actor);
	}

	vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
	renderWindow->AddRenderer(renderer);
	renderWindow->SetSize(640, 480);

	vtkSmartPointer<vtkRenderWindowInteractor> interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
	interactor->SetRenderWindow(renderWindow);

	//启用缩放、旋转和平移交互功能
	vtkSmartPointer<vtkInteractorStyleTrackballCamera> style = vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
	interactor->SetInteractorStyle(style);

	// 渲染并启动交互
	renderWindow->Render();
	interactor->Start();

	return 0;

如果不对多种材料分开提取等值面(定义多个imagedata对象,多次使用MC算法),会出现错误的显示。这个原因可能要追溯到MC算法的原理,暂时不做讨论。

效果如下:

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
VTK提取等值面的等值线,可以使用vtkContourFilter类。vtkContourFilter是一种数据过滤器,可以从输入数据集提取等值线,并生成等值面。以下是使用vtkContourFilter提取等值面的等值线的C++代码实现: ```c++ #include <vtkSmartPointer.h> #include <vtkContourFilter.h> #include <vtkPolyDataMapper.h> #include <vtkActor.h> #include <vtkRenderer.h> #include <vtkRenderWindow.h> #include <vtkRenderWindowInteractor.h> #include <vtkXMLImageDataReader.h> int main(int argc, char* argv[]) { // 读取图像数据 vtkSmartPointer<vtkXMLImageDataReader> reader = vtkSmartPointer<vtkXMLImageDataReader>::New(); reader->SetFileName("volume.vti"); reader->Update(); // 提取等值面的等值线 vtkSmartPointer<vtkContourFilter> contourFilter = vtkSmartPointer<vtkContourFilter>::New(); contourFilter->SetInputConnection(reader->GetOutputPort()); contourFilter->SetValue(0, 200); // 等值参数为200 // 显示等值线 vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New(); mapper->SetInputConnection(contourFilter->GetOutputPort()); mapper->ScalarVisibilityOff(); vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New(); actor->SetMapper(mapper); // 创建渲染器和窗口 vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New(); renderer->AddActor(actor); vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New(); renderWindow->AddRenderer(renderer); // 创建交互器并启动渲染 vtkSmartPointer<vtkRenderWindowInteractor> interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New(); interactor->SetRenderWindow(renderWindow); interactor->Initialize(); renderWindow->Render(); interactor->Start(); return 0; } ``` 在上面的代码,我们首先使用vtkXMLImageDataReader读取了一个VTI格式的图像数据集。然后,我们使用vtkContourFilter提取等值面的等值线,并将其输出连vtkPolyDataMapper的输入端。最后,我们创建了一个vtkActor对象,并将vtkPolyDataMapper设置为其Mapper属性。我们使用vtkRenderWindow和vtkRenderer显示了等值线,并使用vtkRenderWindowInteractor启动了渲染。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值