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写错了定位,修改后就没问题了。

  • 7
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值