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()
相关推荐
菜鸡儿齐16 小时前
Unsafe方法学习
java·python·学习
老师好,我是刘同学20 小时前
Python执行命令并保存输出到文件
python
啵啵鱼爱吃小猫咪1 天前
机械臂阻抗控制github项目-mujoco仿真
开发语言·人工智能·python·机器人
MaximusCoder1 天前
等保测评命令——Centos Linux
linux·运维·经验分享·python·安全·centos
yunyun321231 天前
用Python生成艺术:分形与算法绘图
jvm·数据库·python
m0_662577971 天前
高级爬虫技巧:处理JavaScript渲染(Selenium)
jvm·数据库·python
songyuc1 天前
【PyTorch】感觉`CrossEntropyLoss`和`BCELoss`很类似,为什么它们接收labels的shape常常不一样呢?
人工智能·pytorch·python
ℳ๓₯㎕.空城旧梦1 天前
Python单元测试(unittest)实战指南
jvm·数据库·python
浩子智控1 天前
python程序打包的文件地址处理
开发语言·python·pyqt
Jackey_Song_Odd1 天前
Part 1:Python语言核心 - 序列与容器
开发语言·windows·python