• VTK笔记


    vtk基本概念

    渲染场景中数据的可视化表达通过vtkProp的子类负责,vtkPro子类 负责确定渲染场景中对象的位置、大小和方向等信息,它依赖于两个对象,一个是Mapper对象,负责存放数据和渲染信息,另一个是属性对象(vtkProperty),负责控制颜色、不同明度等

    Mapper作用是将输入的数据转换为几何图元数据

    Model坐标:定义模型时的坐标

    World坐标:放置Actor的三维坐标,就是场景坐标。Actor的一个功能就是将Model坐标转换成World坐标,World坐标同时也是相机、灯光所在的坐标系统

    View坐标是相机所看到的的坐标系统,XYZ取值是[-1,1],相机负责将World坐标转换成View坐标

    Display坐标,就是显示坐标,坐标轴的取值为像素

    渲染引擎负责数据的可视化表达,可视化管线是指用于获取或者创建数据、处理数据以及把数据写入文件或者传递给渲染引擎。

    Source用于创建数据或者读取数据,传入到Filter生成新的数据,再到Mapper后传入引擎。Mapper是可视化管线的终点,也是可视化管线与渲染引擎的桥梁

    可视化管线的连接,通过SetInputConnnection()和GetOutputPort(),连接时要求两部分的数据类型必须一直。如:vtkMarchingCubes要求输入的是vtkImageData类型,如果是vtkPolyData,则运行时出现错误。

    管线执行时,当对数据对象做了更改时,不立即进行计算,只有当发出请求时,才开始计算。程序在调用 Render()函数时,Actor会收到渲染请求,接着请求Mapper给他发送数据,而Mapper会请求上一层的Filter数据,最后Filter请求Source。如果在重新读入数据以后,中间需要某些信息,在得到信息之前,必须调用update()函数。

    vtkSmartPointer<vtkImageData> MyFunction()
    {
        vtkSmartPointer<vtkImageData> myObject = vtkSmartPointer<vtkImageData>::New();
        return myObjec;
    }
    vtkSmartPointer<vtkImageData> myImageData = MyFunction();//可以调用
    
    
    //但是这样不行
    vtkImageData* MyFunction()
    {
        vtkSmartPointer<vtkImageData> myObject = vtkSmartPointer<vtkImageData>::New();
        return myObjec;//返回时转成原始指针,引用计数为0,myObject被删除
    }
    vtkImageData* myImageData = MyFunction();//错误
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    对于这种情况

    vtkSmartPointer<vtkImageData> myObject = vtkSmartPointer<vtkImageData>::New();
    myObject = reader->GetOutput();
    //这里没有必要使用智能指针,因为没有创建新对象。用的是仍然是reader->GetOutput()对象
    //直接使用
    vtkImageData* myObject = reader->GetOutput();
    
    • 1
    • 2
    • 3
    • 4
    • 5

    运行时识别

    vtkSmartPointer<vtkBMPReader> reader = vtkSmartPointer<vtkBMPReader>::New();
    const char* type = reader->GetClassNaem();//"vtkBMPReader"
    if(reader->isA("vtkBMPReader")){}; //true
    
    //基类向子类转换类似于dynamic_cast
    vtkBMPReader::SafeDownCast(readerBase);//只有vtkBMPReader是readerBase的派生类才行,否则返回空指针
    
    //vtk还提供了调试状态输出函数print等
    bmpReader->Print(std::cout);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    vtk数据结构

    数据对象表现的数据是可以被可视化管线处理的数据,只有当数据对象被组织成一种结构后,才能被VTK处理

    vtkDataSet组织结构由拓扑和几何结构两部分组成。vtkDataSet由组织结构和属性数据组成。拓扑:对象构成形式,几何结构:对象空间位置关系。

    Point构成了vtkDataSet的几何结构,Cell构成了拓扑结构。如三角形,必须定义三个坐标点 p1,p2,p3,如何连接(p1-p2-p3还是p3-p2-p1)构成了拓扑。总结,点数据(坐标数据)就是几何结构。其他的都是拓扑结构,如vtkLine、vtkVertex

    一系列有序的点有序的连接就是单元。

    顶点列表由点的索引号表示按照顺序表示。单元由单元类型(六面体)和顶点列表组成,如果不指定单元类型,则不确定形状。

    数据集类型由组织 结构决定,并决定了点和单元之间的相互关系。如网格。

    属性数据,可与点数据或者单元数据相关联,也可以与单元的某些成分相关联,如单元数据 的某个边

    vtkPointData和 vtkCellData表示数据集的属性

    数据通过vtkDataArray的形式存储。元祖的组分个数就是元祖的大小,即每个元组里面有几个值。

    vtk的数据对象是作为vtkDataArray的数组实现。也就是数据数组的数组。

    vtk数据读写

    场景的导入与导出是指将宣传场景中的对象,包括相机、光照 、Actor属性、变化矩阵等写入或者导出文件。

    vtk图像处理

    vtk图形处理

    默认情况下,mapper优先使用点标量数据进行颜色映射,当没有可用的点标量数据时,会使用可用的单元标量数据。

    vtk提供的常用数据源:vtkArrowSource、vtkCubeSource、vtkCylinderSource、vtkDiskSource、vtkLineSource、vtkPlaneSource、vtkSphereSource、vtkConeSource

    vtkMaskPoints设置采样部分数据

    vtkMassProperties计算体积、表面积、最大最小单元面积
    vtkDijkstraGraphGeodesicPath测地距离,两个点沿着模型表面的最短距离
    vtkOutlineFilter包围盒
    vtkPolyDataNormals计算点和单元法向量
    vtkCurvatures计算曲率
    vtkSmoothPolyDataFilter网格平滑
    vtkFeatureEdges封闭性检测
    vtkFillHolesFilter将不封闭的洞填充
    vtkPolyDataConnectivityFilter连通区域分析
    vtkDelaunay2D二维三角剖分

    vtkAppendPolyData可以实现vtkPolyData的合并

    纹理映射,需要将纹理空间的映射分解为两部,需要映入一个包围景物的中介三维曲面作为中介媒介。先将纹理映射到中介面,然后再将中界面映射到物体。

    体绘制

    在这里插入图片描述

    VTK交互与Widget

    //1定义回调函数
    void MyCallbackFunc(vtkObject* obj,unsigned long eid,void* clientdata,void* calldata)
    {
       	//obj,调用时间的对象,即调用AddObserver()函数的对象
        //eid,事件id
        //clentdata,与vtkCallbackCommand实例相关联的数据,回调函数里需要访问主程序里的数据时,由主程序向回调函数传递的数据。可用vtkCallbackCommand::SetClientData()设置
        //calldata,执行vtkObject::InvokeEvent()函数,随着回调函数发送的数据
    }
    //2创建vtkCallBackCommand对象
    	vtkSmartPointer<vtkCallbackCommand> mouseCallback =
    	vtkSmartPointer<vtkCallbackCommand>::New();
    	mouseCallback->SetCallback(MyCallbackFunc);
    //3将vtkCallbackCommand对象添加到观察者列表。
    	interactor->AddObserver(vtkCommand::LeftButtonPressEvent, mouseCallback);
    
    //也可以直接从vtkCommand类中派生子类来实现
    //1、重写类
    class vtkMyCallback : public vtkCommand
    {
    public:
    	static vtkMyCallback *New() 
    	{ return new vtkMyCallback; }
    
    	void SetObject(vtkConeSource* cone)//用于主程序向vtkMyCallback传数据
    	{
    		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;
    };
    //第二步
    	vtkSmartPointer<vtkMyCallback> callback = vtkSmartPointer<vtkMyCallback>::New();
    	callback->SetObject(cone);//cone之前已经定义
    //第三步
    	iren->AddObserver(vtkCommand::LeftButtonPressEvent, callback);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    vtk自定义GUI程序

    vtkEventQtSlotConnect类可以实现VTK事件与Qt槽函数的连接

    vtkEventQtSlotConnect* m_Connections = vtkEventQtSlotConnect::New();
    m_Connections->Connect(m_QVTKWidget->GetRenderWindow()->GetInteractor(),vtkCommand::MouseMouseEvent,this,SLOT(updata(vtkObject*)));
    //槽函数
    void updateCoords(vtkObject* obj)
    {
        vtkRenderWindowInteractor* iren = vtkRenderWindowInteractor::SafeDownCast(obj);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    自定义vtk类

    //1选择基类
    //定义类的构造函数,析构函数,赋值运算符和拷贝构造函数
    //内部都是通过New()静态函数生成,构造、析构、都定义为protected类型,赋值=和拷贝构造都要定义为private,切不做实现
    //2定义标准创建和算出函数 New()和Delete()
    //New()必须覆盖父类的方法,Delete()直接继承vtkObjectBase类即可
    //实现文件构造函数之前,加入vtkStandardNewMacro(myClassName)
    //3定义vtk基本函数。GetClassNameInternal()、IsTypeOf()、IsA()、SafeDownCast()、NewInstanceInternal()、NewInstance()实现这些,不用重写,只是需要vtk宏定义vtkTypeMacro(myClassName,vtkObject)
    //4添加成员变量和相关函数,对于Set()和Get()函数,可以使用vtkSetMacro和vtkGetMacro
    //5增加PrintSelf函数 打印对象状态 调试标志、引用计数等
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
  • 相关阅读:
    Innodb之索引与算法
    关于 Flink 状态与容错机制
    一种影像比对快速提取建筑物要素变化的方法
    【自学HTML笔记第2篇】HTML中的表格标签
    论文回顾:Playful Palette: An Interactive Parametric Color Mixer for Artists
    fastapi定时任务,增量构建可转债交易数据入mongo和qlib
    Spring原理学习(七)JDK动态代理与CGLIB代理底层实现
    自动化测试的神器:selenium,我真的吹爆
    NetApp FAS2554故障灯常亮case处理过程分享
    【多线程进阶】线程安全的集合类
  • 原文地址:https://blog.csdn.net/weixin_44064908/article/details/125415577