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()
相关推荐
进击的明明2 小时前
当AI开始“边想边干”:深入聊聊ReAct,以及如何用Python手搓一个简单Agent
python·面试·agent
全栈弄潮儿3 小时前
Python实战第8期:函数
后端·python·编程语言
卷无止境5 小时前
暗流与破局:AI时代的代码安全审查工具全景指南
后端·python
卷无止境7 小时前
一人公司的全栈选型指南:让 AI Agent 写得快,也让生意跑得稳
后端·python
滴啦嘟啦哒9 小时前
【具身笔记】【π0.5 微调与仿真】五、在MuJoCo中实现可视化仿真
笔记·python·vla·具身
全栈练习生9 小时前
AI安全与红队测试
python·ai
费曼学习法9 小时前
把「发送成功」当「送达」?我排查 IM 长消息被静默吞掉的完整过程
python·ai编程·自动化运维
鸽鸽程序猿9 小时前
【项目】【在线判题系统】b端题目增删改
开发语言·python
NetX行者9 小时前
Python 工程化入门:从脚本到规范的 Python 项目结构
网络·python
MasonYyp10 小时前
asyncio并发协程
python