,
本例 vtkCutter可以配合隐式函数截取数据使用vtkPlane隐式函数配合vtkWidget截取任意平面。
1.读入数据
Create(vtkMultiBlockPLOT3DReader, reader);reader->SetXYZFileName("G:/Temp/vtkTest/combxyz.bin");reader->SetQFileName("G:/Temp/vtkTest/combq.bin");reader->SetScalarFunctionNumber(100);reader->Update();
可以使用其他类型的数据测试。读取的数据文件在《VTK—vtkStructuredGrid提取维度面数据》文章中上传过。
2.定位截取平面
vtkStructuredGrid *grid = (vtkStructuredGrid *) (reader->GetOutput()->GetBlock(0));double bounds[6] = {0};grid->GetBounds(bounds);Create(vtkPlane, plane);plane->SetOrigin((bounds[0] + bounds[1]) * 0.5,(bounds[2] + bounds[3]) * 0.5,(bounds[4] + bounds[5]) * 0.5);plane->SetNormal(0, 0, 1);
初始时隐式函数平面定位在包络框中心,法线指向Z轴正方向。
3.配置vtkCutter
Create(vtkCutter, cutter);cutter->SetCutFunction(plane);cutter->SetInputData(grid);
4.使用vtkPlaneWidget交互定位切割平面
Create(vtkPlaneWidget, widget);widget->SetInteractor(inter);widget->SetDefaultRenderer(render1);widget->SetOrigin(plane->GetOrigin());widget->SetPoint1(bounds[1],(bounds[2] + bounds[3]) * 0.5,(bounds[4] + bounds[5]) * 0.5);widget->SetPoint2((bounds[0] + bounds[1]) * 0.5,bounds[3],(bounds[4] + bounds[5]) * 0.5);widget->EnabledOn();Create(mycallback, callback);callback->m_plane = plane;widget->AddObserver(vtkCommand::InteractionEvent, callback);
4.1小部件四角拖动可调整平面显示大小
4.2鼠标左键点击平面可以任意拖动
4.3鼠标左键点击平面+CTRL键可使平面绕法线旋转
4.4拖动箭头可改变平面角度
4.5鼠标中键可以沿着法线拖动平面
5.完整代码
#include<vtkNew.h>
#include<vtkPlane.h>
#include<vtkCutter.h>
#include<vtkCamera.h>
#include<vtkAutoInit.h>
#include<vtkRenderer.h>
#include<vtkPlaneWidget.h>
#include<vtkRenderWindow.h>
#include<vtkDataSetMapper.h>
#include<vtkStructuredGrid.h>
#include<vtkMultiBlockDataSet.h>
#include<vtkRendererCollection.h>
#include<vtkRenderWindowInteractor.h>
#include<vtkMultiBlockPLOT3DReader.h>VTK_MODULE_INIT(vtkRenderingOpenGL2)
VTK_MODULE_INIT(vtkInteractionStyle)
VTK_MODULE_INIT(vtkRenderingFreeType)#define Create(type,name)\vtkNew<type> name;class mycallback: public vtkCommand
{
public:static mycallback *New() {return new mycallback;}void Execute(vtkObject *caller, unsigned long eventId, void *callData) override{vtkPlaneWidget *widget = (vtkPlaneWidget *)caller;widget->GetPlane(m_plane);}vtkPlane *m_plane;
private:mycallback() {m_plane = nullptr;}~mycallback() {}
};int main()
{Create(vtkMultiBlockPLOT3DReader, reader);reader->SetXYZFileName("G:/Temp/vtkTest/combxyz.bin");reader->SetQFileName("G:/Temp/vtkTest/combq.bin");reader->SetScalarFunctionNumber(100);reader->Update();vtkStructuredGrid *grid = (vtkStructuredGrid *) (reader->GetOutput()->GetBlock(0));double bounds[6] = {0};grid->GetBounds(bounds);Create(vtkPlane, plane);plane->SetOrigin((bounds[0] + bounds[1]) * 0.5,(bounds[2] + bounds[3]) * 0.5,(bounds[4] + bounds[5]) * 0.5);plane->SetNormal(0, 0, 1);Create(vtkCutter, cutter);cutter->SetCutFunction(plane);cutter->SetInputData(grid);Create(vtkDataSetMapper, mapper1);mapper1->SetInputData(grid);Create(vtkActor, actor1);actor1->SetMapper(mapper1);Create(vtkRenderer, render1);render1->AddActor(actor1);render1->SetViewport(0, 0, 0.5, 1);Create(vtkDataSetMapper, mapper2);mapper2->SetInputConnection(cutter->GetOutputPort());Create(vtkActor, actor2);actor2->SetMapper(mapper2);Create(vtkRenderer, render2);render2->AddActor(actor2);render2->SetViewport(0.5, 0, 1, 1);Create(vtkRenderWindow, window);window->AddRenderer(render1);window->AddRenderer(render2);window->GetRenderers()->InitTraversal();Create(vtkRenderWindowInteractor, inter);inter->SetRenderWindow(window);Create(vtkCamera, camera);render1->SetActiveCamera(camera);render2->SetActiveCamera(camera);render1->ResetCamera();Create(vtkPlaneWidget, widget);widget->SetInteractor(inter);widget->SetDefaultRenderer(render1);widget->SetOrigin(plane->GetOrigin());widget->SetPoint1(bounds[1],(bounds[2] + bounds[3]) * 0.5,(bounds[4] + bounds[5]) * 0.5);widget->SetPoint2((bounds[0] + bounds[1]) * 0.5,bounds[3],(bounds[4] + bounds[5]) * 0.5);widget->EnabledOn();Create(mycallback, callback);callback->m_plane = plane;widget->AddObserver(vtkCommand::InteractionEvent, callback);inter->Start();return 0;
}