,
本例 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;
}