GradientBackground 比较不同类型的背景渐变着色模式与坐标转换

一:主要的知识点

1、说明

本文只是教程内容的一小段,因博客字数限制,故进行拆分。主教程链接:vtk教程------逐行解析官网所有Python示例-CSDN博客

2、知识点纪要

本段代码主要涉及的有①背景渐变着色的区分,②vtkCoordinate坐标系统的转化

二:代码及注释

python 复制代码
from vtkmodules.vtkFiltersSources import vtkConeSource, vtkSphereSource
from vtkmodules.vtkIOLegacy import vtkPolyDataReader
from vtkmodules.vtkIOXML import vtkXMLPolyDataReader
from vtkmodules.vtkIOGeometry import vtkOBJReader, vtkBYUReader, vtkSTLReader
from vtkmodules.vtkIOPLY import vtkPLYReader
from vtkmodules.vtkRenderingCore import vtkActor, vtkRenderer, vtkRenderWindow, vtkRenderWindowInteractor, \
    vtkPolyDataMapper, vtkTextMapper, vtkTextProperty, vtkViewport, vtkCoordinate, vtkActor2D, vtkPolyDataMapper2D
from vtkmodules.vtkCommonColor import vtkNamedColors
from vtkmodules.vtkCommonCore import vtkPoints
from vtkmodules.vtkCommonDataModel import (
    vtkCellArray,
    vtkPolyData,
    vtkPolyLine
)


def read_polydata_(path):
    poly_data = vtkPolyData()

    if path is None:
        # Default to a cone if the path is empty.
        source = vtkConeSource()
        source.SetResolution(25)
        source.SetDirection(0, 1, 0)
        source.SetHeight(1)
        source.Update()
        poly_data.DeepCopy(source.GetOutput())
        return poly_data

    valid_suffixes = ['.g', '.obj', '.stl', '.ply', '.vtk', '.vtp']
    ext = path.suffix.lower()
    if path.suffix not in valid_suffixes:
        print('Warning:', path, 'unknown extension, using a sphere instead.')
        source = vtkSphereSource()
        source.SetPhiResolution(50)
        source.SetThetaResolution(50)
        source.Update()
        poly_data.DeepCopy(source.GetOutput())
    else:
        if ext == '.ply':
            reader = vtkPLYReader()
            reader.SetFileName(file_name)
            reader.Update()
            poly_data.DeepCopy(reader.GetOutput())
        elif ext == '.vtp':
            reader = vtkXMLPolyDataReader()
            reader.SetFileName(file_name)
            reader.Update()
            poly_data.DeepCopy(reader.GetOutput())
        elif ext == '.obj':
            reader = vtkOBJReader()
            reader.SetFileName(file_name)
            reader.Update()
            poly_data.DeepCopy(reader.GetOutput())
        elif ext == '.stl':
            reader = vtkSTLReader()
            reader.SetFileName(file_name)
            reader.Update()
            poly_data.DeepCopy(reader.GetOutput())
        elif ext == '.vtk':
            reader = vtkPolyDataReader()
            reader.SetFileName(file_name)
            reader.Update()
            poly_data.DeepCopy(reader.GetOutput())
        elif ext == '.g':
            reader = vtkBYUReader()
            reader.SetGeometryFileName(file_name)
            reader.Update()
            poly_data.DeepCopy(reader.GetOutput())

    return poly_data


def viewport_border(renderer, sides, border_color, border_width):
    """
    在给定的 3D渲染器(vtkRenderer)对应的 2D视口(Viewport)周围绘制一个用户自定义颜色和宽度的边框
    """
    colors = vtkNamedColors()

    """
    先定义点的坐标
    这里的坐标(x, y)是在标准化视口坐标系中定义的,范围从0到1
    (0, 0)代表视口的左下角,(1, 1)代表视口的右上角。这四个点定义了视口区域的四个角
    """
    points = vtkPoints()
    points.SetNumberOfPoints(4)
    points.InsertPoint(0, 1, 1, 0)
    points.InsertPoint(1, 0, 1, 0)
    points.InsertPoint(2, 0, 0, 0)
    points.InsertPoint(3, 1, 0, 0)

    cells = vtkCellArray()
    cells.Initialize()

    if sides[0]:
        # Top
        top = vtkPolyLine()
        top.GetPointIds().SetNumberOfIds(2)
        top.GetPointIds().SetId(0, 0)
        top.GetPointIds().SetId(1, 1)
        cells.InsertNextCell(top)
    if sides[1]:
        # Left
        left = vtkPolyLine()
        left.GetPointIds().SetNumberOfIds(2)
        left.GetPointIds().SetId(0, 1)
        left.GetPointIds().SetId(1, 2)
        cells.InsertNextCell(left)
    if sides[2]:
        # Bottom
        bottom = vtkPolyLine()
        bottom.GetPointIds().SetNumberOfIds(2)
        bottom.GetPointIds().SetId(0, 2)
        bottom.GetPointIds().SetId(1, 3)
        cells.InsertNextCell(bottom)
    if sides[3]:
        # Right
        right = vtkPolyLine()
        right.GetPointIds().SetNumberOfIds(2)
        right.GetPointIds().SetId(0, 3)
        right.GetPointIds().SetId(1, 0)
        cells.InsertNextCell(right)

    poly = vtkPolyData()
    poly.Initialize()
    poly.SetPoints(points)
    poly.SetLines(cells)

    """
    vtkCoordinate 负责处理 不同坐标系统之间的坐标转换,特别是在渲染(Renderer)和显示(Display)过程中
    简单来说  vtkCoordinate就是用来表示并转换一个点在不同坐标系统中的位置
    vtk中常见的坐标系统
    名称       英文标识                     描述                       
   
    世界坐标     **World**                三维空间中物体的真实坐标(例如几何模型的点位置) 
    视图坐标     **View**                 相机变换后的坐标(相机坐标系)          
    规范化视口坐标  **Normalized Viewport**  渲染窗口中的归一化坐标,范围 [0,1]     
    视口坐标     **Viewport**             渲染窗口内的像素坐标(受相机投影影响)      
    显示坐标     **Display**              屏幕上的实际像素坐标(例如鼠标点击位置)     
    规范化显示坐标  **Normalized Display**   屏幕归一化坐标,范围 [0,1]         

    """
    coordinate = vtkCoordinate()
    coordinate.SetCoordinateSystemToNormalizedViewport()  # 设置 coordinate 的坐标系统为 Normalized Viewport(规范化视口坐标系)

    mapper = vtkPolyDataMapper2D()
    mapper.SetInputData(poly)
    mapper.SetTransformCoordinate(coordinate)

    actor = vtkActor2D()
    actor.SetMapper(mapper)
    actor.GetProperty().SetColor(colors.GetColor3d(border_color))

    actor.GetProperty().SetLineWidth(border_width)

    renderer.AddViewProp(actor)


def main():
    fp = None
    pd = read_polydata_(fp)

    ren_win = vtkRenderWindow()
    ren_win.SetWindowName('GradientBackground')

    iren = vtkRenderWindowInteractor()
    renderers = []

    modes = [
        vtkViewport.GradientModes.VTK_GRADIENT_VERTICAL,
        vtkViewport.GradientModes.VTK_GRADIENT_HORIZONTAL,
        vtkViewport.GradientModes.VTK_GRADIENT_RADIAL_VIEWPORT_FARTHEST_SIDE,
        vtkViewport.GradientModes.VTK_GRADIENT_RADIAL_VIEWPORT_FARTHEST_CORNER,
    ]
    """
    模式(Mode),描述,渐变方向
    VTK_GRADIENT_VERTICAL,垂直渐变,从底部 (SetBackground) 到顶部 (SetBackground2) 颜色过渡。
    VTK_GRADIENT_HORIZONTAL,水平渐变,从左侧 (SetBackground) 到右侧 (SetBackground2) 颜色过渡。
    VTK_GRADIENT_RADIAL_VIEWPORT_FARTHEST_SIDE,径向渐变(最远边),从中心 (SetBackground) 向视口最远的那条边进行径向扩散渐变,直到边缘变为 SetBackground2 的颜色。
    VTK_GRADIENT_RADIAL_VIEWPORT_FARTHEST_CORNER,径向渐变(最远角),从中心 (SetBackground) 向视口最远的那个角进行径向扩散渐变,直到角落变为 SetBackground2 的颜色。
    """

    colors = vtkNamedColors()

    mapper = vtkPolyDataMapper()
    mapper.SetInputData(pd)

    actor = vtkActor()
    actor.SetMapper(mapper)
    actor.GetProperty().SetColor(colors.GetColor3d('Honeydew'))
    actor.GetProperty().SetSpecular(0.3)
    actor.GetProperty().SetSpecularPower(60.0)

    ren_width = 640
    ren_height = 480

    xmins = [0.0, 0.5, 0.0, 0.5]
    ymins = [0.0, 0.0, 0.5, 0.5]
    xmaxs = [0.5, 1.0, 0.5, 1.0]
    ymaxs = [0.5, 0.5, 1.0, 1.0]

    bottom_color = colors.GetColor3d('Gold')
    top_color = colors.GetColor3d('OrangeRed')
    left_color = colors.GetColor3d('Gold')
    right_color = colors.GetColor3d('OrangeRed')
    center_color = colors.GetColor3d('Gold')
    side_color = colors.GetColor3d('OrangeRed')
    corner_color = colors.GetColor3d('OrangeRed')

    viewport_title = ["Vertical",
                      "Horizontal",
                      "Radial Farthest Side",
                      "Radial Farthest Corner",
                      ]

    text_property = vtkTextProperty()
    text_property.SetJustificationToCentered()
    text_property.SetFontSize(ren_height // 12)
    text_property.SetColor(colors.GetColor3d('MidnightBlue'))

    text_mappers = []
    text_actors = []

    lb = [False, True, True, False]
    lbr = [False, True, True, True]
    tlb = [True, True, True, False]
    tlbr = [True, True, True, True]
    border_color = 'DarkGreen'
    border_width = 4.0

    for i in range(0, 4):
        text_mappers.append(vtkTextMapper())
        text_mappers[i].SetInput(viewport_title[i])
        text_mappers[i].SetTextProperty(text_property)

        text_actors.append(vtkActor2D())
        text_actors[i].SetMapper(text_mappers[i])
        text_actors[i].SetPosition(ren_width / 2, 8)

        renderers.append(vtkRenderer())
        renderers[i].AddActor(text_actors[i])
        renderers[i].AddActor(actor)
        renderers[i].GradientBackgroundOn()
        renderers[i].SetGradientMode(modes[i])

        renderers[i].SetViewport(xmins[i], ymins[i], xmaxs[i], ymaxs[i])

        if i == 1:
            # Horizontal
            renderers[i].SetBackground(left_color)
            renderers[i].SetBackground2(right_color)
            viewport_border(renderers[i], lbr, border_color, border_width)
        elif i == 2:
            # Radial Farthest Side
            renderers[i].SetBackground(center_color)
            renderers[i].SetBackground2(side_color)
            viewport_border(renderers[i], tlb, border_color, border_width)
        elif i == 3:
            # Radial Farthest Corner
            renderers[i].SetBackground(center_color)
            renderers[i].SetBackground2(corner_color)
            viewport_border(renderers[i], tlbr, border_color, border_width)
        else:
            # Vertical
            renderers[i].SetBackground(bottom_color)
            renderers[i].SetBackground2(top_color)
            viewport_border(renderers[i], lb, border_color, border_width)
        ren_win.AddRenderer(renderers[i])
    ren_win.SetInteractor(iren)
    ren_win.Render()

    iren.Initialize()
    iren.UpdateSize(ren_width * 2, ren_height * 2)

    iren.Start()


if __name__ == '__main__':
    file_name = ""
    main()
相关推荐
2601_962382433 小时前
python快乐编程网络爬虫课后答案
python·网络爬虫·学习工具·课后答案·刷题app
鹏哥带你干乡墅3 小时前
优选乡墅赋能培训平台如何帮助提升乡村建设?
大数据·人工智能·python
veminhe4 小时前
python调用接口获取网络信息
python
Allen_LVyingbo5 小时前
医疗AI基础2026-构建可靠智能体的编程路径(上)
大数据·数据库·人工智能·python·自动化
Rnan-prince5 小时前
堆与TopK · 从零到通透 —— 9 节全系列复盘
python·算法
2601_962294616 小时前
Python接口自动化测试实战:使用requests库
python·接口自动化测试·异常处理·requests库·api测试
砚底藏山河6 小时前
【量化纯GET实战 #23】多股票相关性:用收益率看板块联动
java·数据库·python·金融·数据分析
阿童木写作7 小时前
跨境电商翻译工具推荐:批量图片翻译+视频字幕实时翻译
人工智能·python·音视频
晶捷软件7 小时前
晶捷智能:集团型制造企业ERP如何实现多工厂统一管控
大数据·人工智能·python·制造
oyguyteggytrrwwwrt7 小时前
闵可夫斯基差演示
python