VTK————3D模型的旋转、交互、透明度设置

模型旋转

旋转模型的话可以用到以下例程,但是每次设置选择坐标时,都是累加的。可以通过SetOrientation来将模型方向设为初试方向。如果三个坐标都使用较大值来进行旋转,那么由于累加的特性。模型会在空间内进行大幅度的旋转和位移,这是需要注意的。

cpp 复制代码
void rotate( double x, double y, double z,int mode){

    if (Actor== nullptr) {

        return;
    }
    if(mode==1){
    // 将模型的方向设置为初始方向(0度旋转)
    Actor->SetOrientation(0, 0, 0);

    // 触发渲染以更新视图
    render->interactor()->Render();

    }
    else{
    Actor->RotateX(x);
    Actor->RotateY(y);
    Actor->RotateZ(z);
    3DRender->AddActor(m_modelActor);

    }

    render->interactor()->Render();

}

也可以通过设置interactor 的 style 为 vtkInteractorStyleTrackballActor,来使用鼠标来控制 STL 模型的位置和方向。

cpp 复制代码
    // Set the interaction style to vtkInteractorStyleTrackballActor
    vtkSmartPointer<vtkInteractorStyleTrackballActor> style = 
        vtkSmartPointer<vtkInteractorStyleTrackballActor>::New();
    m_renderWidget[3]->interactor()->SetInteractorStyle(style);

但是,存在一个问题,vtkInteractorStyleTrackballActor 和 vtkInteractorStyleTrackballCamera 之间存在冲突,因为它们控制不同的对象。vtkInteractorStyleTrackballActor 控制的是 actors,而 vtkInteractorStyleTrackballCamera 控制的是 camera,这样会导致无法实现3D模型的交互。

一种可能的解决方案是创建一个自定义的 interactor style,它在不同的模式下切换 vtkInteractorStyleTrackballActor 和 vtkInteractorStyleTrackballCamera。例如,当用户按下一个特定的键(比如 "c")时,切换到 camera 控制模式,当用户按下另一个键(比如 "a")时,切换到 actor 控制模式。

cpp 复制代码
class CustomInteractorStyle : public vtkInteractorStyleTrackballCamera
{
public:
    static CustomInteractorStyle* New();
    vtkTypeMacro(CustomInteractorStyle, vtkInteractorStyleTrackballCamera);

    virtual void OnKeyPress() override
    {
        // Get the keypress
        vtkRenderWindowInteractor *rwi = this->Interactor;
        std::string key = rwi->GetKeySym();

        // Output the key that was pressed
        std::cout << "Pressed " << key << std::endl;

        // Handle an arrow key
        if(key == "a")
        {
            vtkInteractorStyleTrackballActor::SafeDownCast(rwi->GetInteractorStyle())->OnKeyPress();
        }
        else if(key == "c")
        {
            vtkInteractorStyleTrackballCamera::SafeDownCast(rwi->GetInteractorStyle())->OnKeyPress();
        }

        // Forward events
        vtkInteractorStyleTrackballCamera::OnKeyPress();
    }

private:

};

vtkStandardNewMacro(CustomInteractorStyle);

透明度设置

compositeOpacity:这是一个分段线性函数,用于定义不同灰度值的体素的透明度。函数的每个点由四个值定义:灰度值,透明度,左斜率和右斜率。例如,在 compositeOpacity->AddPoint(-3024, 0, 0.5, 0.0) 中,-3024 是灰度值,0 是该灰度值的透明度,0.5 和 0.0 分别是左斜率和右斜率。

color:这是一个颜色传递函数,用于定义不同灰度值的体素的颜色。函数的每个点由五个值定义:灰度值,红色分量,绿色分量,蓝色分量,中间点和中间点的斜率。例如,在 color->AddRGBPoint(-3024, 0, 0, 0, 0.5, 0.0) 中,-3024 是灰度值,0, 0, 0 分别是红色、绿色和蓝色分量,0.5 和 0.0 分别是中间点和中间点的斜率。

这两个函数通常一起使用来定义体绘制的颜色和透明度。在这个例子中,compositeOpacity 和 color 传递函数的灰度值是相同的,这意味着对于给定的灰度值,颜色和透明度都会被定义。

cpp 复制代码
    vtkNew<vtkPiecewiseFunction> compositeOpacity;
    compositeOpacity->AddPoint(-3024, 0, 0.5, 0.0);
    compositeOpacity->AddPoint(-16, 0, .49, .61);
    compositeOpacity->AddPoint(641, 0.5, .5, 0.0);
    compositeOpacity->AddPoint(3071, 0.5, 0.5, 0.0);

    vtkNew<vtkColorTransferFunction> color;
    color->AddRGBPoint(-3024, 0, 0, 0, 0.5, 0.0);
    color->AddRGBPoint(-16, 0.73, 0.25, 0.30, 0.49, .61);
    color->AddRGBPoint(641, .90, .82, .56, .5, 0.0);
    color->AddRGBPoint(3071, 1, 1, 1, .5, 0.0);

如果想要实时调整模型的透明度,可以在QT界面上绑定QSlider部件,然后根据槽函数机制,来设定透明度大小。QSlider 只支持整型,而不支持浮点数(double)。但可以通过一些技巧来实现这个效果。首先,将滑块的最小值设置为0,最大值设置为20,因为1 / 0.05 = 20,这样你可以得到0.05的步进。

值得注意的是,不一定要局限于把透明度最大值设为1,超出1以后的透明值也能带来意料之外的效果。

cpp 复制代码
    ui->horizontalSlider->setMinimum(0); // 最小值
    ui->horizontalSlider->setMaximum(20); // 最大值
    connect(ui->horizontalSlider, SIGNAL(valueChanged(int)), this, SLOT(on_sliderValueChanged(int)));

void on_ValueChanged(int value)
{
    double doubleValue = value / 20.0;
    vtkNew<vtkPiecewiseFunction> compositeOpacity;
    compositeOpacity->AddPoint(-3024, 0, 0.5, 0.0);
    compositeOpacity->AddPoint(-16, 0, .49, .61);
    compositeOpacity->AddPoint(641,doubleValue, .5, 0.0);
    compositeOpacity->AddPoint(3071, doubleValue, 0.5, 0.0);


    Volume->GetProperty()->SetScalarOpacity(newCompositeOpacity);
    render->interactor()->Render();

}
相关推荐
Mr.Q18 分钟前
Qt多边形填充/不填充绘制
qt
霁月风26 分钟前
设计模式——适配器模式
c++·适配器模式
jrrz08281 小时前
LeetCode 热题100(七)【链表】(1)
数据结构·c++·算法·leetcode·链表
可峰科技1 小时前
斗破QT编程入门系列之二:认识Qt:编写一个HelloWorld程序(四星斗师)
开发语言·qt
咖啡里的茶i1 小时前
Vehicle友元Date多态Sedan和Truck
c++
海绵波波1071 小时前
Webserver(4.9)本地套接字的通信
c++
@小博的博客1 小时前
C++初阶学习第十弹——深入讲解vector的迭代器失效
数据结构·c++·学习
爱吃喵的鲤鱼2 小时前
linux进程的状态之环境变量
linux·运维·服务器·开发语言·c++
7年老菜鸡3 小时前
策略模式(C++)三分钟读懂
c++·qt·策略模式
Ni-Guvara3 小时前
函数对象笔记
c++·算法