maltadirk 发表于 2022-1-12 09:49

VTK实践_5(图型处理)

前言

图形处理应用非常广泛,每个角色的模型、场景都是图形数据,基本都在VTKPolyData包中。
它是由几何数据、模型数据、拓扑数据组成。几何数据为主要的组成模型的点集;拓扑是这些点连成的单元数据;属性数据将几何数据与拓扑数据进行关联。
例子

1、vtkpolydata数据的生成与显示
        vtkSmartPointer<vtkConeSource> coneSource =//锥体图形
                vtkSmartPointer<vtkConeSource>::New();
        coneSource->Update();

        vtkSmartPointer<vtkPolyData> cone = coneSource->GetOutput();//vtkpolydata设置其点数以及单元数目
        //int nPoints = cone->GetNumberOfPoints();
        //int nCells= cone->GetNumberOfCells();

        //std::cout<<"Points number:"<<nPoints<<std::endl;
        //std::cout<<"Cellsnumber:"<<nCells<<std::endl;

        vtkSmartPointer<vtkPolyDataMapper> mapper =//图像数据转化为渲染图形,进而进行输出
                vtkSmartPointer<vtkPolyDataMapper>::New();
        mapper->SetInputData(cone);上述例子就是通过vtkConeSource进行一个体绘制。
2、vtkpolydata数据数据的创建
/**********************************************************************
通过vtkpoint进行点的创建
通过vtkolpolygon进行多边形的定义
通过vtkTriangle定义其三角形
vtkCellArray存储其体,然后进行管程的显示
**********************************************************************/

#include <vtkSmartPointer.h>
#include <vtkPolygon.h>
#include <vtkTriangle.h>
#include <vtkCellArray.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkProperty.h>

#include <iostream>

int main(int argc, char *argv[])
{
        vtkSmartPointer<vtkPoints> points =//设置点集
                vtkSmartPointer<vtkPoints>::New();
        points->InsertNextPoint(0.0, 0.0, 0.0);
        points->InsertNextPoint(1.0, 0.0, 0.0);
        points->InsertNextPoint(1.0, 1.0, 0.0);
        points->InsertNextPoint(0.0, 1.0, 0.0);
        points->InsertNextPoint(2.0, 0.0, 0.0);

        vtkSmartPointer<vtkPolygon> polygon =//通过ID进行多边形定义
                vtkSmartPointer<vtkPolygon>::New();
        polygon->GetPointIds()->SetNumberOfIds(4);
        polygon->GetPointIds()->SetId(0, 0);
        polygon->GetPointIds()->SetId(1, 1);
        polygon->GetPointIds()->SetId(2, 2);
        polygon->GetPointIds()->SetId(3, 3);

        vtkSmartPointer<vtkTriangle> trianle =//通过ID进行三角形定义
                vtkSmartPointer<vtkTriangle>::New();
        trianle->GetPointIds()->SetId(0, 1);
        trianle->GetPointIds()->SetId(1, 2);
        trianle->GetPointIds()->SetId(2, 4);

        vtkSmartPointer<vtkCellArray> cells =//vtkCellArray用于存储所有的单元数据
                vtkSmartPointer<vtkCellArray>::New();
        cells->InsertNextCell(polygon);
        cells->InsertNextCell(trianle);

        vtkSmartPointer<vtkPolyData> polygonPolyData =
                vtkSmartPointer<vtkPolyData>::New();
        polygonPolyData->SetPoints(points);
        polygonPolyData->SetPolys(cells);

        vtkSmartPointer<vtkPolyDataMapper> mapper =
                vtkSmartPointer<vtkPolyDataMapper>::New();
        mapper->SetInputData(polygonPolyData);

        vtkSmartPointer<vtkActor> actor =
                vtkSmartPointer<vtkActor>::New();
        actor->SetMapper(mapper);

        vtkSmartPointer<vtkRenderer> renderer =
                vtkSmartPointer<vtkRenderer>::New();
        renderer->AddActor(actor);
        renderer->SetBackground(0.5, 0.5, 0.5);

        vtkSmartPointer<vtkRenderWindow> renderWindow =
                vtkSmartPointer<vtkRenderWindow>::New();
        renderWindow->AddRenderer(renderer);
        renderWindow->SetSize( 640, 480 );
        renderWindow->Render();
        renderWindow->SetWindowName("PolyDataNew");


        vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
                vtkSmartPointer<vtkRenderWindowInteractor>::New();
        renderWindowInteractor->SetRenderWindow(renderWindow);

        renderWindow->Render();
        renderWindowInteractor->Start();

        return EXIT_SUCCESS;
}3、vtkpolydata的相关属性数据
        //几何结构数据:点集
        vtkSmartPointer<vtkPoints> pts =
                vtkSmartPointer<vtkPoints>::New();
        pts->InsertNextPoint(0.0, 0.0, 0.0);
        pts->InsertNextPoint(1.0, 0.0, 0.0);
        pts->InsertNextPoint(1.0, 1.0, 0.0);
        pts->InsertNextPoint(0.0, 1.0, 0.0);
        pts->InsertNextPoint(2.0, 0.0, 0.0);
        //拓扑结构数据:正四边形
        vtkSmartPointer<vtkPolygon> polygon =
                vtkSmartPointer<vtkPolygon>::New();
        polygon->GetPointIds()->SetNumberOfIds(4);
        polygon->GetPointIds()->SetId(0, 0);
        polygon->GetPointIds()->SetId(1, 1);
        polygon->GetPointIds()->SetId(2, 2);
        polygon->GetPointIds()->SetId(3, 3);
        //拓扑结构数据:三角形
        vtkSmartPointer<vtkTriangle> triangle =
                vtkSmartPointer<vtkTriangle>::New();
        triangle->GetPointIds()->SetId(0, 1);
        triangle->GetPointIds()->SetId(1, 2);
        triangle->GetPointIds()->SetId(2, 4);
        //构成拓扑结构集合
        vtkSmartPointer<vtkCellArray> cells =
                vtkSmartPointer<vtkCellArray>::New();
        cells->InsertNextCell(polygon);
        cells->InsertNextCell(triangle);
        //合成几何拓扑结构用于显示
        vtkSmartPointer<vtkPolyData> polygonPolyData =
                vtkSmartPointer<vtkPolyData>::New();
        polygonPolyData->SetPoints(pts);
        polygonPolyData->SetPolys(cells);

        //添加属性结构:颜色
        unsigned char red = { 255, 0, 0 };
        unsigned char green = { 0, 255, 0 };
        unsigned char blue = { 0, 0, 255 };
        vtkSmartPointer<vtkUnsignedCharArray> ptColor =//为点设置颜色数据
                vtkSmartPointer<vtkUnsignedCharArray>::New();
        ptColor->SetNumberOfComponents(3);//指定其组分数的大小
        //ptColor->InsertNextTypedTuple(red);
        ptColor->InsertNextTypedTuple(red);//顺序的插入到整个数据中
        ptColor->InsertNextTypedTuple(green);//顺序的插入元组数据:颜色
        ptColor->InsertNextTypedTuple(blue);
        ptColor->InsertNextTypedTuple(red);
        ptColor->InsertNextTypedTuple(green);
        polygonPolyData->GetPointData()->SetScalars(ptColor);//通过GetPointData起作用

        vtkSmartPointer<vtkUnsignedCharArray> cellColor =//为单元设置颜色数据
                vtkSmartPointer<vtkUnsignedCharArray>::New();
        cellColor->SetNumberOfComponents(3);
        cellColor->InsertNextTypedTuple(blue);
        cellColor->InsertNextTypedTuple(red);
        polygonPolyData->GetCellData()->SetScalars(cellColor);//通过GetCellData起作用

        vtkSmartPointer<vtkPolyDataMapper> mapper =//映射,用于输出
                vtkSmartPointer<vtkPolyDataMapper>::New();
        mapper->SetInputData(polygonPolyData);设置点,进而通过其进行组分颜色的设置
4、基本的图像操作
前言:vtk提供很多的图形操作,比如:VTKMath欧几里得的计算、向量的模等;VTKLine提供点线之间的距离,线线之间的距离操作等;vtkTriangle提供了面积、内接圆等;vtkpolyon提供了法向量、重心等的计算;vtkTetra提供四边形体积等的计算。vtkmassproperties实现三角形表面积与体积的计算,,但是必须要求其是封闭的图形:这个时候有专门的函数提供封闭性检验。vtkTriangle Filter实现多边形网络向正方形网络数据的转换
/利用vtkMassProperties计算三角网络模型的表面积、体积**/
vtkSmartPointer<vtkCubeSource> cubeSource = //正方形
                vtkSmartPointer<vtkCubeSource>::New();
        cubeSource->Update();

        vtkSmartPointer<vtkTriangleFilter> triFilter = //多边的网络数据向三角形网络数据的转换
                vtkSmartPointer<vtkTriangleFilter>::New();
        triFilter->SetInputData(cubeSource->GetOutput());
        triFilter->Update();

        vtkSmartPointer<vtkMassProperties> massProp = //基本的图像操作;计算
                vtkSmartPointer<vtkMassProperties>::New();
        massProp->SetInputData(triFilter->GetOutput());//图像的输入
        //massProp->SetInputData(triFilter->GetOutput());
        float vol = massProp->GetVolume();//体积
        float area= massProp->GetSurfaceArea();//表面积
        float maxArea = massProp->GetMaxCellArea();//最大单元面积
        float minArea = massProp->GetMinCellArea();//最小单元面积

        std::cout<<"Volume      :"<<vol<<std::endl;
        std::cout<<"Surface Area:"<<area<<std::endl;
        std::cout<<"Max Area    :"<<maxArea<<std::endl;
        std::cout<<"Min Area    :"<<minArea<<std::endl;
        //管线
        vtkSmartPointer<vtkPolyDataMapper> mapper = //映射显示
                vtkSmartPointer<vtkPolyDataMapper>::New();
        //mapper->SetInput(cubeSource->GetOutput());
        mapper->SetInputData(triFilter->GetOutput());

4.2、图形处理之测地距离
就是在体的表面计算点的距离
//测地:必须设定点的标号
        vtkSmartPointer<vtkDijkstraGraphGeodesicPath> dijkstra = //通过迪杰斯特拉进行数据的测量
                vtkSmartPointer<vtkDijkstraGraphGeodesicPath>::New();
        dijkstra->SetInputData(sphereSource->GetOutput());
        dijkstra->SetStartVertex(0);//开始点
        dijkstra->SetEndVertex(10);//结束点
        dijkstra->Update();
        //映射转换输出:线
        vtkSmartPointer<vtkPolyDataMapper> pathMapper =
                vtkSmartPointer<vtkPolyDataMapper>::New();
        pathMapper->SetInputData(dijkstra->GetOutput());
       
        vtkSmartPointer<vtkActor> pathActor =
                vtkSmartPointer<vtkActor>::New();
        pathActor->SetMapper(pathMapper);
        pathActor->GetProperty()->SetColor(1,0,0);
        pathActor->GetProperty()->SetLineWidth(4);
        //映射转换输出:体
        vtkSmartPointer<vtkPolyDataMapper> mapper =
                vtkSmartPointer<vtkPolyDataMapper>::New();
        mapper->SetInputData(sphereSource->GetOutput());
        //输出
        vtkSmartPointer<vtkActor> actor =
                vtkSmartPointer<vtkActor>::New();
        actor->SetMapper(mapper);


4.4、包围盒的定义
vtkSmartPointer<vtkSphereSource> sphereSource =//定义一个球体
                vtkSmartPointer<vtkSphereSource>::New();
        sphereSource->SetCenter(0.0, 0.0, 0.0);
        sphereSource->SetRadius(5.0);
        sphereSource->Update();
       
        vtkPolyData* sphere = sphereSource->GetOutput();

        vtkSmartPointer<vtkOutlineFilter> outline =//包围盒的定义
                vtkSmartPointer<vtkOutlineFilter>::New();
        outline->SetInputData(sphere);//定义包围盒
        outline->Update();//算法执行完毕,必须更新!!!
        //管线 4.5、法向量的计算
垂直于该平面的三维向量
#include <vtkSmartPointer.h>
#include <vtkPolyDataReader.h>
#include <vtkPolyDataNormals.h> //计算法向量
#include <vtkMaskPoints.h>
#include <vtkArrowSource.h>
#include <vtkGlyph3D.h>
#include <vtkPointData.h>
#include <vtkProperty.h>
//reader->SetFileName();
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>

int main()
{
        vtkSmartPointer<vtkPolyDataReader> plyReader =//输入一个vtk的图像
                vtkSmartPointer<vtkPolyDataReader>::New();
        plyReader->SetFileName("../data/fran_cut.vtk");
        plyReader->Update();

        vtkSmartPointer<vtkPolyDataNormals> normFilter =//设置其法向量的参数
                vtkSmartPointer<vtkPolyDataNormals>::New();
        normFilter->SetInputData(plyReader->GetOutput());
        normFilter->SetComputePointNormals(1);//开启点法向量计算
        normFilter->SetComputeCellNormals(0); //关闭单元法向量计算
        normFilter->SetAutoOrientNormals(1);
        normFilter->SetSplitting(0);
        normFilter->Update();

        vtkSmartPointer<vtkMaskPoints> mask =//平滑项,面具的平滑
                vtkSmartPointer<vtkMaskPoints>::New();
        mask->SetInputData(normFilter->GetOutput());
        mask->SetMaximumNumberOfPoints(300);
        mask->RandomModeOn();
        mask->Update();

        vtkSmartPointer<vtkArrowSource> arrow =//设置箭头数据
                vtkSmartPointer<vtkArrowSource>::New();
        arrow->Update(); //一定要更新 否则数据没有添加进来,程序会报错
        //对想添加的数据点进行符号标注
        vtkSmartPointer<vtkGlyph3D> glyph =//为每个输入点拷贝相应方向和伸缩比例的轮廓几何体
                vtkSmartPointer<vtkGlyph3D>::New();
        glyph->SetInputData(mask->GetOutput());
        glyph->SetSourceData(arrow->GetOutput());//每一点用箭头代替
        glyph->SetVectorModeToUseNormal();//设置向量显示模式和法向量一致
        glyph->SetScaleFactor(0.01); //设置伸缩比例
        glyph->Update();

        vtkSmartPointer<vtkPolyDataMapper> mapper =
                vtkSmartPointer<vtkPolyDataMapper>::New();
        mapper->SetInputData(plyReader->GetOutput());
        vtkSmartPointer<vtkPolyDataMapper> normMapper =
                vtkSmartPointer<vtkPolyDataMapper>::New();
        normMapper->SetInputData(normFilter->GetOutput());
        vtkSmartPointer<vtkPolyDataMapper> glyphMapper =
                vtkSmartPointer<vtkPolyDataMapper>::New();//带法向量的图像
        glyphMapper->SetInputData(glyph->GetOutput());

        vtkSmartPointer<vtkActor> actor =
                vtkSmartPointer<vtkActor>::New();
        actor->SetMapper(mapper);
        vtkSmartPointer<vtkActor> normActor =
                vtkSmartPointer<vtkActor>::New();
        normActor->SetMapper(normMapper);
        vtkSmartPointer<vtkActor> glyphActor =
                vtkSmartPointer<vtkActor>::New();
        glyphActor->SetMapper(glyphMapper);
        glyphActor->GetProperty()->SetColor(1, 0, 0);

        double origView = { 0, 0, 0.33, 1 };
        double normView = { 0.33, 0, 0.66, 1 };
        double glyphView = { 0.66, 0, 1, 1 };
        vtkSmartPointer<vtkRenderer> origRender =
                vtkSmartPointer<vtkRenderer>::New();
        origRender->SetViewport(origView);
        origRender->AddActor(actor);
        origRender->SetBackground(1, 0, 0);
        vtkSmartPointer<vtkRenderer> normRender =
                vtkSmartPointer<vtkRenderer>::New();
        normRender->SetViewport(normView);
        normRender->AddActor(normActor);
        normRender->SetBackground(0, 1, 0);
        vtkSmartPointer<vtkRenderer> glyphRender =
                vtkSmartPointer<vtkRenderer>::New();
        glyphRender->SetViewport(glyphView);
        glyphRender->AddActor(glyphActor);
        glyphRender->AddActor(normActor);
        glyphRender->SetBackground(0, 0, 1);

        vtkSmartPointer<vtkRenderWindow> rw =
                vtkSmartPointer<vtkRenderWindow>::New();
        rw->AddRenderer(origRender);
        rw->AddRenderer(normRender);
        rw->AddRenderer(glyphRender);
        rw->SetWindowName("Calculating Point Norm & Cell Norm");
        rw->SetSize(960, 320);
        rw->Render();

        vtkSmartPointer<vtkRenderWindowInteractor> rwi =
                vtkSmartPointer<vtkRenderWindowInteractor>::New();
        rwi->SetRenderWindow(rw);
        rwi->Initialize();
        rwi->Start();

        return 0;
}
页: [1]
查看完整版本: VTK实践_5(图型处理)