VTK交互之vtkCommand

vtk中oberver和command的信息机制详解 vtk 阅读详情
AI摘要

本文介绍VTK中利用观察者/命令模式实现交互的两种方法:通过定义回调函数和继承vtkCommand类。通过示例详细展示了如何实现左键点击事件。

观察者/命令模式

  VTK的交互除了可以监听来自鼠标、键盘等外部设备的消息,还可以在渲染场景中生成功能各异的交互部件(Widget),用于控制可化过程的参数,达到用户渲染要求。
   在VTK中要实现与数据的交互,可以基于观察者/命令模式。可以通过两种方法来实现该模式:一种是通过定义回调函数;另外一种是通过从vtkCommand类派生子类。二者的实现过程基本类似,都是通过AddObserver监听感兴趣的时间,然后在回调函数或者vtkCommand::Execute()函数里实现所需的功能。
   观察者/命令模式(Observer/Command)是VTK里用得较多的设计模式。VTK中绝大多数的类派生自vtkObject。查看vtkObject的接口可以找到AddObserver()、RemoveObserver()、GetCommand()等函数。

一、事件回调函数

VTK里使用回调函数实现观察者/命令模式主要分为以下三个步骤。
1、定义回调函数。回调函数的函数签名只能是以下形式:

void func(vtkObject* obj, unsigned long eid, void* clientdata, void* calldata)

其中

  • obj是调用事件的对象(即调用AddObserver()函数的主题对象,例如interactor);
  • eid为所要监听的事件ID,VTK中的事件定义在vtkCommand.h文件中;
  • clientdata是与vtkCalbackCommand实例相关的数据。简单说,是指回调函数里需要访问主程序里的数据时,由主程序向回调函数传递的数据,可以通过vtkCallbackCommand::SetClientData()函数设置。
  • calldata是执行vtkObject::InvokeEvent()函数时,随着回调函数发送的数据,比如当调用ProgressEvent事件时,会自动发送当前的进度值作为calldata。

2、创建一个vtkCallbackCommand对象,并调用vtkCallbackCommand::SetCallback()函数设置所定义的回调函数。

vtkSmartPointer<vtkCallbackCommand> mouseCallback = vtkSmartPointer<vtkCallbackCommand>::New();
mouseCallback->SetCallback(MyCallbackFunc);

3、将vtkCallbackCommand对象添加到主题对象的观察者列表中。

interactor->AddObserver(vtkCommand::LeftButtonPressEvent, mouseCallback);

示例说明

CMakeLists.txt文件代码如下:

CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
PROJECT(CallbackFunction)
FIND_PACKAGE(VTK REQUIRED)
INCLUDE(${VTK_USE_FILE})
ADD_EXECUTABLE(CallbackFunction    CallbackFunction.cpp)
TARGET_LINK_LIBRARIES(CallbackFunction ${VTK_LIBRARIES})

CallbackFunction.cpp文件代码如下:

#include <vtkSmartPointer.h>
#include <vtkPNGReader.h>
#include <vtkImageViewer2.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkCallbackCommand.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>

long pressCounts = 0;

//第一步,定义回调函数。注意回调函数的签名,不能更改。
void MyCallbackFunc(vtkObject*, unsigned long eid, void* clientdata, void *calldata)
{
    std::cout<<"You have clicked: "<<++pressCounts<<" times."<<std::endl;
}

int main()
{
    vtkSmartPointer<vtkPNGReader> reader = vtkSmartPointer<vtkPNGReader>::New();
    reader->SetFileName("E:\\TestData\\VTK-logo.png");

    vtkSmartPointer<vtkImageViewer2> viewer = vtkSmartPointer<vtkImageViewer2>::New();
    viewer->SetInputConnection(reader->GetOutputPort());

    vtkSmartPointer<vtkRenderWindowInteractor> interactor =  vtkSmartPointer<vtkRenderWindowInteractor>::New();
    viewer->SetupInteractor(interactor);
    viewer->Render();

    viewer->GetRenderer()->SetBackground(1.0, 1.0, 1.0);
    viewer->SetSize(640, 480);
    viewer->GetRenderWindow()->SetWindowName("事件回调函数");

    //第二步,设置回调函数。
    vtkSmartPointer<vtkCallbackCommand> mouseCallback = 
        vtkSmartPointer<vtkCallbackCommand>::New();
    mouseCallback->SetCallback ( MyCallbackFunc );

    //第三步,将vtkCallbackCommand对象添加到观察者列表。
    interactor->SetRenderWindow(viewer->GetRenderWindow());
    interactor->AddObserver(vtkCommand::LeftButtonPressEvent, mouseCallback);

    interactor->Initialize();
    interactor->Start();

    return EXIT_SUCCESS;
}

运行结果:
这里写图片描述

二、vtkCommand子类

写vtkCommand的子类来实现观察者/命令模式,分为以下三个步骤。
1、从vtkCommand类派生出子类,并实现vtkCommand::Execute()函数,该函数原型是:

virtual void Exeute(vtkObject* caller, unsigned long eventId, void* callData) = 0;

Execute()是纯虚函数,所以从vtkCommand派生的类都必须实现这个方法。

2、在主程序中实例化一个vtkCommand子类的对象以及调用相关的方法。

3、调用AddObserver()函数监听感兴趣的事件。

示例说明

CMakeLists.txt文件代码如下:

CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
PROJECT(Command)
FIND_PACKAGE(VTK REQUIRED)
INCLUDE(${VTK_USE_FILE})
ADD_EXECUTABLE(Command    Command.cpp)
TARGET_LINK_LIBRARIES(Command ${VTK_LIBRARIES})

Command.cpp文件代码如下:

#include <vtkSmartPointer.h>
#include <vtkConeSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkCamera.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkCommand.h>
#include <vtkBoxWidget.h>
#include <vtkTransform.h>
#include <vtkInteractorStyleTrackballCamera.h>

//第一步
class vtkMyCommand : public vtkCommand
{
public:
    static vtkMyCommand *New()
    {
        return new vtkMyCommand;
    }

    void SetObject(vtkConeSource* cone)
    {
        m_Cone = cone;
    }

    virtual void Execute(vtkObject *caller, unsigned long eventId, void* callData)
    {
        std::cout<<"Left button pressed.\n"
            <<"The Height: "<<m_Cone->GetHeight()<<"\n"
            <<"The Radius: "<<m_Cone->GetRadius()<<std::endl;
    }

private:
    vtkConeSource *m_Cone;
};

int main()
{
    vtkSmartPointer<vtkConeSource> cone = vtkSmartPointer<vtkConeSource>::New();
    cone->SetHeight( 3.0 );
    cone->SetRadius( 1.0 );
    cone->SetResolution( 10 );

    vtkSmartPointer<vtkPolyDataMapper> coneMapper = 
        vtkSmartPointer<vtkPolyDataMapper>::New();
    coneMapper->SetInputConnection( cone->GetOutputPort() );

    vtkSmartPointer<vtkActor> coneActor = vtkSmartPointer<vtkActor>::New();
    coneActor->SetMapper( coneMapper );

    vtkSmartPointer<vtkRenderer> ren1= vtkSmartPointer<vtkRenderer>::New();
    ren1->AddActor( coneActor );
    ren1->SetBackground( 0.1, 0.4, 0.9 );

    vtkSmartPointer<vtkRenderWindow> renWin =
        vtkSmartPointer<vtkRenderWindow>::New();
    renWin->AddRenderer( ren1 );
    renWin->SetSize( 640, 480 );
    renWin->Render();
    renWin->SetWindowName("vtkCommand子类");

    vtkSmartPointer<vtkRenderWindowInteractor> iren = 
        vtkSmartPointer<vtkRenderWindowInteractor>::New();
    iren->SetRenderWindow(renWin);

    vtkSmartPointer<vtkInteractorStyleTrackballCamera> style = 
        vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
    iren->SetInteractorStyle(style);

    //第二步
    vtkSmartPointer<vtkMyCommand> callback = vtkSmartPointer<vtkMyCommand>::New();
    callback->SetObject(cone);

    //第三步
    iren->AddObserver(vtkCommand::LeftButtonPressEvent, callback);

    iren->Initialize();
    iren->Start();

    return EXIT_SUCCESS;
}

运行结果:
这里写图片描述

总结:

  在VTK中,用观察者/命令模式实现交互,一般有两种方法:1、实例化vtkCallbackCommand,将自己写的回调函数,设给其;2、从vtkCommand类派生出子类,重写Execute方法。

VTK API 28:vtkCommand — 事件处理系统 vtkCommand是VTK事件处理系统的核心类,采用观察者设计模式,用于定义事件响应的回调接口。事件发送者(vtkObject及其子类)触发事件。事件监听者通过继承vtkCommand实现回调逻辑。监听者注册到事件发送者,事件发生时执行对应回调。vtkCommand的设计极大增强了VTK的可扩展性和灵活性,是VTK响应用户交互、管线更新等机制的基础。创建事件发送者(如vtkObject及其子类)。定义事件回调类,继承自vtkCommand,实现Execute()。将回调注册到发送者的指定事件,使用。 阅读详情

相关推荐

ActiViz实战:鼠标交互和vtkCommand的问题

在C++的VTK中,我们常用vtkCallbackCommand来触发回调,利用观察者/命令模式,实现vtkCommand中的事件。示例代码MessageBox.Show("鼠标双击了!");观察者/命令模式不可用,原因未知;鼠标单击事件可用,双击事件不触发。目前发现的ActiViz鼠标交互问题就以上这些,如果大家有什么新发现,可评论留言。

仰望星空的博客 926

VTK交互功能-callback/observe模式-vtkCommand

本博文为系列博文,尝试将vtk交互功能讲清楚,包括常用的接口分析、常用的交互逻辑以及常用的交互Widget。若各位小伙伴有需要请多多关注,也希望能给各位小伙伴有所帮助。vtkCommand作为callback/obseve交互模式的基类,提供了很多基础和可继承的方法,那么我们就从vtkCommand开始。

qq_40041064的博客 1387

Observer与Command模式在VTK类库设计中的应用研究

VTK 作为一套开源的三维可视化开发库在国外越来越被广泛使用.但国内对VKT 内部机制研究相对较少,因而应用受到了限制.Observer 和Command 是软件设计模式的两个分支.灵活的运用这两种模式.提高了VTK的可重用性和扩充性.本文从设计模式的角度,详细阐述了VTK 中消息事件响应的机制,并对VTK 这种设计模式的优点进行了分析,最后通过实例说明了VTK 设计模式的应用.

VTK Observer和Command模式详解

本文记录一些在VTK开发中遇到的一些细节问题。

此曲只应天上有的博客 846

【国民技术N32项目移植】基于 Windows 的 ARM GCC 开发环境

【国民技术N32项目移植】基于 Windows 的 ARM GCC 开发环境

weixin_42150032的博客 1361

海洋与地质地理信息数据下载网站汇总集锦

各种海洋与地质地理信息数据集合

qq_36980284的博客 1268

VTK交互功能-callback/observe模式

本博文为系列博文,尝试将vtk交互功能讲清楚,包括常用的接口分析、常用的交互逻辑以及常用的交互Widget。若各位小伙伴有需要请多多关注,也希望能给各位小伙伴有所帮助。小结:本博文主要讲述vtk交互功能中的callback/observe模式。

qq_40041064的博客 1421

【SOC估算】基于EKF与神经网络融合的锂电池SOC高精度估计及Matlab实现

本文探讨了基于EKF与神经网络融合的锂电池SOC高精度估计方法。通过结合扩展卡尔曼滤波(EKF)的模型驱动优势和神经网络的数据驱动学习能力,实现了对电池荷电状态(SOC)的精准预测。Matlab仿真验证了该混合算法在各种工况下均能显著降低估计误差,提升电池管理系统性能。

play7的博客 695

VTK修炼之道71:交互与Widget_观察者/命令模式

1.前言 一个强大的可视化系统不仅需要强大的数据处理能力,也需要方便易用的交互功能。图形处理软件ParaView(hhttp://www.paraview.org)、德国癌症研究中心研发的MITK(http://www.mitk.org)等开源软件系统都提供了强大的交互功能,作为ParaView、MITK等软件构件基础的VTK同样也提供了各种各样的交互功能。 VTK的交互除了可以监听来自鼠

沈春旭的博客 6762

学习笔记( 11 ) - 解决:finalshell连接虚拟机(ubuntu)超时,主机ping不通虚拟机,主机没有VMnet8网卡, Connection refused: connect

解决:finalshell连接虚拟机(ubuntu)超时,主机ping不通虚拟机,主机没有VMnet8网卡, Connection refused: connect

烟溪彭于晏的博客 2万+

AutoSAR配置视频讲解:简介

AutoSAR实验视频讲解:闪烁一颗LED实验【简介】 大家好,欢迎来到雪云飞星的《AutoSAR实验课的视频讲解》专栏。看过《AutoSAR入门到精通系列讲解》的朋友们应该对博主不陌生,有很多朋友加了博主的微信成为了好友,还有朋友约过线下见面,博主很高兴大家能从我的博客中获得一些收获。在专栏里博主挖了很多坑,当时也说过想要录制一个AutoSAR的配置视频教程,素材在20年初就已经录好,中间各种原因足足鸽了一年。当时因为一些技术原因只能通过博客的图文形式展示出来,现在我们剪辑了视频,请了专业的配音,希望以视

雪云飞星的博客 9653

vtk两种交互形式

VTK有两种不同的方法可以控制交互风格。第一种是使用vtkInteractorStyle的子类,可以是VTK自带的或者是你自行编写的类。第二种是添加Observer监听vtkRenderWindowInteractor里的事件,定义一系列回调函数(或命令)来实现交互。 1.观察者/命令模式(Observe/Command) 观察者/命令模式是VTK里用的比较多的设计模式。 VTK中绝大多数的类都派生自vtkObject。查看类vtkObject的接口可以找到AddObserve()、RemoveObs

simple的博客 1644

解决微信小程序长页面滚动到底部点击底部的输入框后输入框漂浮且页面滚动到顶部

一、问题描述 项目中有一个长页面上部展示部分信息下部为信息录入,页面长度为三屏幕(不同手机屏幕大小略有差异),当滚动到第二屏或者第三屏去填写信息时点击输入框后输入框漂浮起来了并且页面向上滚动了一段距离,回到了第一屏中展示的内容。效果如图。 滚动到第二屏,证件号输入。 点击输入框 可以看到证件号输入框漂浮了起来并且页面滚动到了第一屏展示的内容。 注意:小程序是2018年上线,在2020年4月份之前该页面从未出现过这种现象。推测:微信的后续更新中对微信小程序基础库进行了重构,导致点击输入框后页

仰望星空的代码 3259

VTK中oberver 和 command 的信息机制详解

前言 看了东灵出版的书的第八章,有点迷糊,这里简单做些笔记。 正文 观察者/命令模式(Observer / Command) 目的: 实现VTK的交互功能 定义: 一个vtkObject (包括它的子类) 可以拥有多个 Observer。  就是观察者在对象的状态发生改变时,调用相应的函数或者说是执行预定的动作。 实现 事件回调函数 示例 //第一步,定义

Jane_yuhui的专栏 3618

Xilinx高级调试方法--远程调试

本文主要介绍Xilinx的一些高级调试方法,以及如何使用Xilinx的相关IP。

斌赋的博客 3308

海思图像质量之HiPQTool调试

文章目录一. HiPQTool 界面二. 图像调试三. 将调试参数写入程序中 一. HiPQTool 界面 二. 图像调试 三. 将调试参数写入程序中

lzg2011的博客 2378

VTK知识学习(50)- 交互与Widget(一)

一个强大的可视化系统不仅需要强大的数据处理能力,也需要方便易用的交互功能。图形处理软件ParaView(http://www.paraview.org)、德国癌症研究中心研发的MITK(http://www.mitk.org)等开源软件系统都提供了强大的交互功能,作为ParaView、MITK 等软件构建基础的 VTK 同样也提供了各种各样的交互功能。

weixin_45114627的博客 2076

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

VTK中的三种事件响应机制

列举VTK中的三种事件响应机制并简要分析

suqiangchuan2752的博客 1343

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

关于VTK默认交互方式和鼠标左键进行交互的两种方式

1

huihui__huihui的博客 1679

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

VTK常用交互类的解析

与 vtkInteractorStyleTrackballActor 不同,vtkInteractorStyleTrackballCamera 的操作是针对相机的,因此会影响观察场景的方式,而不是单独的对象。: vtkInteractorStyleTrackballActor 是一个交互风格类,它允许用户通过使用鼠标来旋转、移动和缩放场景中的演员(actor),这些演员是渲染管线中的实体,代表了可视化的数据。用户可以通过鼠标直接与场景中的对象交互,而不是与整个场景或相机交互。

weixin_52443865的博客 470

vtk如何实现事件回调、交互的创建

创建交互事件类,继承对应的vtkInteractorStyle。创建回调事件类,继承vtkCommand。

小蝈蝈的博客 587

VTK:交互与Widget——观察者/命令模式

1.绪论 一个强大的可视化系统不仅需要强大的数据处理能力,也需要方便易用的交互功能。图形处理软件ParaView、 德国癌症研究中心研发的MITK等开源软件系统都提供了强大的交互功能。VTK的交互功能除了可以监听来自鼠标、键盘等外部设备的消息,还可以在渲染场景中生成功能各异的交互部件(Widget),用于控制可视化过程的参数,达到用户的渲染要求。 2.观察者/命令模式 1.观察者/命令者是VTK里用比较多的设计模式。VTK中绝大多数的类都派生自vtkObject。查看类vtkObject的接口可以找到

m0_45306991的博客 954

VTK交互(三维图像切片切换)

命令模式是属于对象行为模式,它把请求封装为一个对象,并提供一致性发送请求的接口,当一个事件发生时,它不直接把事件传递给事件的调用者,而是在命令和调用者之间增加一个中间者,将这种直接关系切断,同时将两者都隔离。其是指 一个 对象 可以有多个观察者(Observer),当该对象的状态发生改变时,所以依赖于它的观察者(Observer)对象都得到通知而被自动更新。vtk交互功能主要是通过 观察者/命令模式(Observer/Command)来实现。(使用回调函数来实现 键盘 上键和下键 ,三维图像切片的切换)

S^S 1024

vtk数据交互的两种方式之回调函数、vtkCommand

vtk

Littlehero_121的博客 1808

VTK_Learning_交互与Widget_观察者/命令模式

1.前言 一个强大的可视化系统不仅需要强大的数据处理能力,也需要方便易用的交互功能。图形处理软件ParaView(hhttp://www.paraview.org)、德国癌症研究中心研发的MITK(http://www.mitk.org)等开源软件系统都提供了强大的交互功能,作为ParaView、MITK等软件构件基础的VTK同样也提供了各种各样的交互功能。 VTK的交互除了可以监听来自鼠标、...

weixin_38293453的博客 323

2.3、vtk事件交互回调

VTK事件回调机制可基于命令/观察员模式,包含事件、观察员和命令三个核心要素。主要实现方式有:1)继承vtkCommand子类重写Execute();2)使用vtkCallbackCommand绑定独立函数;3)继承vtkInteractorStyle定制交互逻辑;4)使用vtkWidget组件内置回调;5)VTK6.0+支持信号槽机制。

m0_62123442的博客 377
上一篇: 设计模式之观察者模式
下一篇: 设计模式之状态模式
暮-成-雪
博客等级 码龄12年 5328粉丝 319原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值