DeformPointSet 基于控制网格(Control Mesh)的 3D 几何体形变

一:主要的知识点

1、说明

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

2、知识点纪要

本段代码主要涉及的有①vtkElevationFilter的标量分配方法,②vtkDeformPointSet的网格变形方法简介

二:代码及注释

python 复制代码
import vtkmodules.vtkInteractionStyle
import vtkmodules.vtkRenderingOpenGL2
from vtkmodules.vtkCommonCore import vtkPoints
from vtkmodules.vtkCommonDataModel import vtkPolyData, vtkCellArray
from vtkmodules.vtkFiltersSources import vtkSphereSource
from vtkmodules.vtkRenderingCore import vtkActor, vtkRenderer, vtkRenderWindow, vtkRenderWindowInteractor, \
    vtkPolyDataMapper
from vtkmodules.vtkCommonColor import vtkNamedColors
from vtkmodules.vtkFiltersCore import vtkElevationFilter
from vtkmodules.vtkFiltersGeneral import vtkDeformPointSet


def main():
    colors = vtkNamedColors()

    # 创建一个球形去变形
    sphere = vtkSphereSource()
    sphere.SetThetaResolution(51)
    sphere.SetPhiResolution(17)
    sphere.Update()

    bounds = sphere.GetOutput().GetBounds()

    """
    vtkElevationFilter   为 3D 几何体中的顶点分配标量值(Scalar Values)
    这些标量值通常用于表示高程(Elevation)或沿着某一方向的渐变
    简而言之,它根据每个点在 3D 空间中沿着一条指定直线的投影位置,来计算一个数值,并将这个数值作为该点的属性数据
    用户通过 SetLowPoint(x_L, y_L, z_L) 和 SetHighPoint(x_H, y_H, z_H) 定义了一条直线
    对于输入几何体上的每一个顶点 P,过滤器计算 P 沿着这条直线方向的投影距离
    位于 LowPoint 处的投影值被映射为最低的标量值(默认 0)
    位于 HighPoint 处的投影值被映射为最高的标量值(默认 1)
    位于两者之间的点,其标量值通过线性插值得到
    """
    ele = vtkElevationFilter()
    ele.SetInputConnection(sphere.GetOutputPort())
    ele.SetLowPoint((bounds[1] + bounds[0]) / 2.0,
                    (bounds[3] + bounds[2]) / 2.0,
                    -bounds[5])
    ele.SetHighPoint((bounds[1] + bounds[0]) / 2.0,
                     (bounds[3] + bounds[2]) / 2.0,
                     bounds[5])
    ele.Update()

    pts = vtkPoints()
    pts.SetNumberOfPoints(6)
    pts.SetPoint(0,
                 bounds[0] - 0.1 * (bounds[1] - bounds[0]),
                 (bounds[3] + bounds[2]) / 2.0,
                 (bounds[5] + bounds[4]) / 2.0)
    pts.SetPoint(1,
                 bounds[1] + 0.1 * (bounds[1] - bounds[0]),
                 (bounds[3] + bounds[2]) / 2.0,
                 (bounds[5] + bounds[4]) / 2.0)
    pts.SetPoint(2,
                 (bounds[1] + bounds[0]) / 2.0,
                 bounds[2] - 0.1 * (bounds[3] - bounds[2]),
                 (bounds[5] + bounds[4]) / 2.0)
    pts.SetPoint(3,
                 (bounds[1] + bounds[0]) / 2.0,
                 bounds[3] + 0.1 * (bounds[3] - bounds[2]),
                 (bounds[5] + bounds[4]) / 2.0)
    pts.SetPoint(4,
                 (bounds[1] + bounds[0]) / 2.0,
                 (bounds[3] + bounds[2]) / 2.0,
                 bounds[4] - 0.1 * (bounds[5] - bounds[4]))
    pts.SetPoint(5,
                 (bounds[1] + bounds[0]) / 2.0,
                 (bounds[3] + bounds[2]) / 2.0,
                 bounds[5] + 0.1 * (bounds[5] - bounds[4]))


    tris = vtkCellArray()

    cells = [[2, 0, 4], [1, 2, 4], [3, 1, 4], [0, 3, 4], [0, 2, 5], [2, 1, 5], [1, 3, 5], [3, 0, 5]]

    for cell in cells:
        tris.InsertNextCell(3)
        for c in cell:
            tris.InsertCellPoint(c)

    pd = vtkPolyData()
    pd.SetPoints(pts)
    pd.SetPolys(tris)

    meshMapper = vtkPolyDataMapper()
    meshMapper.SetInputData(pd)

    meshActor = vtkActor()
    meshActor.SetMapper(meshMapper)
    meshActor.GetProperty().SetRepresentationToWireframe()  # 只展示结构
    meshActor.GetProperty().SetColor(colors.GetColor3d('Black'))


    """
    vtkDeformPointSet  基于控制网格的3D几何体形变的过滤器
    允许用户通过操作一个简单的"笼子"或"控制网格"来平滑地、直观地改变复杂模型的形状,而无需直接修改模型本身的数千甚至数百万个顶点
    
    基于控制网格的形变,需要输入对象,即要被形变的3D模型,控制对象,一个简单的,由用户定义的3D网格,必须包裹住输入对象
    
    对于球体内部的任何一个点 P vtkDeformPointSet 算法需要回答一个问题:
    "如果我移动笼子上的某个顶点 P control,球体上的 P sphere 应该移动多少?"
    答案由插值权重 wi决定。对于球体上的一个点 Psphere,它与笼子上的所有顶点 P 
    control,i都有一个权重 wi关联,且所有权重之和 ∑w i 通常等于 1。
    权重 w i的含义:w i越大,表示 P sphere 距离 P 
    control,i越近,或受其影响越大。w i越小(接近 0),表示影响越小。
    计算这些权重的方法有很多种(如均值坐标法或径向基函数),但它们都依赖于笼子的拓扑结构来确定 P 
    sphere在笼子内部的相对位置
    """

    deform = vtkDeformPointSet()
    deform.SetInputData(ele.GetOutput())
    deform.SetControlMeshData(pd)
    deform.Update()

    # 移动控制点,使其发生变形,如果没有下面的这几行代码,球体不会发生形变
    controlPoint = pts.GetPoint(5)
    pts.SetPoint(5, controlPoint[0],
                 controlPoint[1],
                 bounds[5] + .8 * (bounds[5] - bounds[4]))
    pts.Modified()

    polyMapper = vtkPolyDataMapper()
    polyMapper.SetInputConnection(deform.GetOutputPort())
    polyActor = vtkActor()
    polyActor.SetMapper(polyMapper)

    renderer = vtkRenderer()
    renWin = vtkRenderWindow()
    renWin.AddRenderer(renderer)
    iren = vtkRenderWindowInteractor()
    iren.SetRenderWindow(renWin)

    renderer.AddActor(polyActor)
    renderer.AddActor(meshActor)

    renderer.GetActiveCamera().SetPosition(1, 1, 1)
    renderer.ResetCamera()
    renderer.SetBackground(colors.GetColor3d('DarkSlateGray'))

    renWin.SetSize(300, 300)
    renWin.SetWindowName('DeformPointSet')
    renWin.Render()

    iren.Start()

if __name__ == '__main__':
    main()
相关推荐
木心术119 小时前
openclaw与Hermes的优劣势对比
人工智能·python·opencv·自动化
潇洒畅想19 小时前
1.2 希腊字母速查表 + 公式阅读实战
java·人工智能·python·算法·rust·云计算
深度学习lover19 小时前
<数据集>yolo 瓶盖识别<目标检测>
人工智能·python·yolo·计算机视觉·瓶盖识别
测绘第一深情19 小时前
MapQR:自动驾驶在线矢量化高精地图构建的端到端 SOTA 方法
数据结构·人工智能·python·神经网络·算法·机器学习·自动驾驶
高洁0119 小时前
AI算法实战:逻辑回归在风控场景中的应用
人工智能·python·深度学习·transformer
书香门第20 小时前
搭建免费的Ollama AI Agent
人工智能·python·ollama
小白学大数据20 小时前
分布式爬虫核心技术详解与工程实践
开发语言·分布式·爬虫·python
Ulyanov20 小时前
打造现代化雷达电子对抗仿真界面 第二篇:雷达电子对抗仿真系统核心功能实现
前端·python·信息可视化·数据可视化·系统仿真·雷达电子战
财经资讯数据_灵砚智能20 小时前
基于全球经济类多源新闻的NLP情感分析与数据可视化(夜间-次晨)2026年4月12日
人工智能·python·信息可视化·自然语言处理·ai编程
测试秃头怪20 小时前
python&selenium自动化测试实战项目详解
自动化测试·软件测试·python·selenium·测试工具·职场和发展·测试用例