VTK—vtkImplicitFunction 隐函数

通过这个例子可以直观理解隐函数是什么、在空间中怎么分布、怎么布尔运算。
1.完整代码
#include<vtkBox.h>
#include<vtkNew.h>
#include<vtkActor.h>
#include<vtkSphere.h>
#include<vtkAutoInit.h>
#include<vtkProperty.h>
#include<vtkRenderer.h>
#include<vtkImageData.h>
#include<vtkContourFilter.h>
#include<vtkImplicitBoolean.h>
#include<vtkDataSetMapper.h>
#include<vtkRenderWindow.h>
#include<vtkPolyDataMapper.h>
#include<vtkSampleFunction.h>
#include<vtkRenderWindowInteractor.h>#include<vtkActor2D.h>
#include<vtkTextActor.h>
#include<vtkTextProperty.h>
#include<vtkCommand.h>
#include<vtkSliderWidget.h>
#include<vtkSliderRepresentation2D.h>VTK_MODULE_INIT(vtkRenderingOpenGL2)
VTK_MODULE_INIT(vtkInteractionStyle)
VTK_MODULE_INIT(vtkRenderingFreeType)#include<QString>class myCallback: public vtkCommand
{
public:static myCallback *New() {return new myCallback;}void Execute(vtkObject *caller, unsigned long eventId, void *callData) override{vtkSliderWidget *widget = (vtkSliderWidget *)caller;vtkSliderRepresentation2D *slider = (vtkSliderRepresentation2D *)widget->GetRepresentation();m_contour1->SetValue(0, slider->GetValue());m_contour2->SetValue(0, slider->GetValue());m_contour3->SetValue(0, slider->GetValue());}vtkContourFilter *m_contour1;vtkContourFilter *m_contour2;vtkContourFilter *m_contour3;private:myCallback() {m_contour1 = nullptr;m_contour2 = nullptr;m_contour3 = nullptr;}~myCallback() {}
};#define Create(type,name)\vtkNew<type> name;int main()
{//两个隐函数,方盒子和球Create(vtkBox, box);box->SetBounds(-1, 1, -1, 1, -1, 1);Create(vtkSphere, sphere);sphere->SetRadius(1);sphere->SetCenter(1, 0, 0);//隐函数布尔加Create(vtkImplicitBoolean, add);add->SetOperationTypeToUnion();add->AddFunction(box);add->AddFunction(sphere);Create(vtkSampleFunction, addSample);addSample->SetModelBounds(-5, 5, -5, 5, -5, 5);addSample->SetSampleDimensions(50, 50, 50);addSample->SetImplicitFunction(add);Create(vtkContourFilter, contour1);contour1->SetInputConnection(addSample->GetOutputPort());contour1->SetValue(0, 0);Create(vtkDataSetMapper, mapper1);mapper1->SetInputConnection(contour1->GetOutputPort());Create(vtkActor, actor1);actor1->SetMapper(mapper1);actor1->GetProperty()->SetEdgeVisibility(true);//隐函数布尔异Create(vtkImplicitBoolean, diff);diff->SetOperationTypeToDifference();diff->AddFunction(box);diff->AddFunction(sphere);Create(vtkSampleFunction, diffSample);diffSample->SetModelBounds(-5, 5, -5, 5, -5, 5);diffSample->SetSampleDimensions(50, 50, 50);diffSample->SetImplicitFunction(diff);Create(vtkContourFilter, contour2);contour2->SetInputConnection(diffSample->GetOutputPort());contour2->SetValue(0, 0);Create(vtkDataSetMapper, mapper2);mapper2->SetInputConnection(contour2->GetOutputPort());Create(vtkActor, actor2);actor2->SetMapper(mapper2);actor2->GetProperty()->SetEdgeVisibility(true);//隐函数布尔交Create(vtkImplicitBoolean, section);section->SetOperationTypeToIntersection();section->AddFunction(box);section->AddFunction(sphere);Create(vtkSampleFunction, secSample);secSample->SetModelBounds(-5, 5, -5, 5, -5, 5);secSample->SetSampleDimensions(50, 50, 50);secSample->SetImplicitFunction(section);Create(vtkContourFilter, contour3);contour3->SetInputConnection(secSample->GetOutputPort());contour3->SetValue(0, 0);Create(vtkDataSetMapper, mapper3);mapper3->SetInputConnection(contour3->GetOutputPort());Create(vtkActor, actor3);actor3->SetMapper(mapper3);actor3->GetProperty()->SetEdgeVisibility(true);//左上角窗口Create(vtkRenderer, render1);render1->AddActor(actor1);//render1->SetViewport(0, 0, 0.5, 1); 这里错了,难怪坐标系统混乱了render1->SetViewport(0, 0.5, 0.5, 1);//右上角窗口Create(vtkRenderer, render2);render2->AddActor(actor2);render2->SetViewport(0.5, 0.5, 1, 1);//右下角窗口Create(vtkRenderer, render3);render3->AddActor(actor3);render3->SetViewport(0.5, 0, 1, 0.5);//左上角窗口Create(vtkRenderer, render4);render4->SetViewport(0, 0, 0.5, 0.5);Create(vtkRenderWindow, window);window->AddRenderer(render1);window->AddRenderer(render2);window->AddRenderer(render3);window->AddRenderer(render4);Create(vtkRenderWindowInteractor, interactor);interactor->SetRenderWindow(window);//显示汉字的方式Create(vtkTextProperty, textProperty);textProperty->SetJustificationToCentered();textProperty->SetVerticalJustificationToCentered();textProperty->SetFontFamily(VTK_FONT_FILE);textProperty->SetFontFile("C:/WINDOWS/FONTS/MSYHL.TTC");//这里多renderer的坐标系统很迷惑,上面Render修改了,没有疑惑了Create(vtkTextActor, topLeft);topLeft->SetTextScaleModeToNone();topLeft->SetTextProperty(textProperty);topLeft->GetPositionCoordinate()->SetCoordinateSystemToNormalizedViewport();topLeft->GetPositionCoordinate()->SetValue(0.2, 0.8);topLeft->SetInput("布尔加");render1->AddActor(topLeft);Create(vtkTextActor, topRight);topRight->SetTextScaleModeToNone();topRight->SetTextProperty(textProperty);topRight->GetPositionCoordinate()->SetCoordinateSystemToNormalizedViewport();topRight->GetPositionCoordinate()->SetValue(0.2, 0.8);topRight->SetInput("布尔减");render2->AddActor(topRight);Create(vtkTextActor, bottemRight);bottemRight->SetTextScaleModeToNone();bottemRight->SetTextProperty(textProperty);bottemRight->GetPositionCoordinate()->SetCoordinateSystemToNormalizedViewport();bottemRight->GetPositionCoordinate()->SetValue(0.2, 0.8);bottemRight->SetInput("布尔交");render3->AddActor(bottemRight);//滑动条Create(vtkSliderWidget, widget);Create(vtkSliderRepresentation2D, slider);slider->SetMinimumValue(-1);slider->SetMaximumValue(5);slider->SetValue(0);widget->SetRepresentation(slider);widget->SetAnimationModeToOff();widget->SetInteractor(interactor);widget->SetDefaultRenderer(render4);//滑动条在右侧窗口不显示,有点疑惑,上面render修改了,这里没疑惑了slider->GetPoint1Coordinate()->SetCoordinateSystemToNormalizedViewport();slider->GetPoint1Coordinate()->SetValue(0.2, 0.5);slider->GetPoint2Coordinate()->SetCoordinateSystemToNormalizedViewport();slider->GetPoint2Coordinate()->SetValue(0.8, 0.5);widget->EnabledOn();//回调Create(myCallback, callback);callback->m_contour1 = contour1;callback->m_contour2 = contour2;callback->m_contour3 = contour3;widget->AddObserver(vtkCommand::InteractionEvent, callback);interactor->Start();return 0;
}
1.隐函数的布尔运算
void SetOperationTypeToUnion(); //并集
void SetOperationTypeToIntersection(); //交集
void SetOperationTypeToDifference(); //差集
void SetOperationTypeToUnionOfMagnitudes(); //尚未理解
2.对隐函数空间采样
Create(vtkSampleFunction, diffSample);
diffSample->SetModelBounds(-5, 5, -5, 5, -5, 5); //采样空间范围
diffSample->SetSampleDimensions(50, 50, 50); //XYZ方向点数
diffSample->SetImplicitFunction(diff);
//输入隐函数,对空间中的点坐标按照隐函数规则进行计算
3.提取等值面
Create(vtkContourFilter, contour2);
contour2->SetInputConnection(diffSample->GetOutputPort());
contour2->SetValue(0, 0);
初始值是0,就是隐函数对应的默认特征。后面通过滑动条改变这个值,可以看到几何特征变大变小。其他值代表了对默认特征的偏离程度,负值向内,正值向外。
4.四个视口显示
//左上角窗口Create(vtkRenderer, render1);render1->AddActor(actor1);render1->SetViewport(0, 0, 0.5, 1);//右上角窗口Create(vtkRenderer, render2);render2->AddActor(actor2);render2->SetViewport(0.5, 0.5, 1, 1);//右下角窗口Create(vtkRenderer, render3);render3->AddActor(actor3);render3->SetViewport(0.5, 0, 1, 0.5);//左上角窗口Create(vtkRenderer, render4);render4->SetViewport(0, 0, 0.5, 0.5);
5.显示汉字需要特殊处理
//显示汉字的方式Create(vtkTextProperty, textProperty);textProperty->SetJustificationToCentered();textProperty->SetVerticalJustificationToCentered();textProperty->SetFontFamily(VTK_FONT_FILE);textProperty->SetFontFile("C:/WINDOWS/FONTS/MSYHL.TTC");
5.1将字体家族设置为VTK_FONT_FILE,表示从文件获取
5.2获取电脑中的字体文件,此处是微软雅黑,C:/WINDOWS/FONTS/MSYHL.TTC
5.3这样处理之后就可以愉快的输入汉字了
6.多个Renderer中的定位很迷惑
topLeft->GetPositionCoordinate()->SetValue(0.2, 0.9);
topRight->GetPositionCoordinate()->SetValue(0.2, 0.8);
bottemRight->GetPositionCoordinate()->SetValue(0.2, 0.8);
slider->GetPoint1Coordinate()->SetValue(0.2, 0.5);
与单个renderer中理解的不一致,还没搞明白。
修正:问题不在这里,在于左上角的render写错了定位,修改后就没问题了。
