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()
相关推荐
笨鸟先飞,勤能补拙3 小时前
AI 赋能网络安全:技术全景、成熟度评估与实战案例
人工智能·python·安全·web安全·网络安全·sqlite·github
长和信泰光伏储能3 小时前
京津冀光伏发电:绿色能源的未来之路
python·能源
浦信仿真大讲堂4 小时前
从重复操作到自动化闭环:如何让 CST 与 Python 真正协同起来
python·自动化·cst·仿真软件·达索软件
Gu Gu Study4 小时前
ScoutLoop开放域深度研究引擎(agent的初步设计想法)
人工智能·python
卷无止境5 小时前
写代码这件事,到底该讲究点什么?
后端·python
卷无止境5 小时前
循环复杂度到底在算什么,Python 代码怎么才能写得让人一看就懂
后端·python
lpfasd1235 小时前
MediaCrawler 项目深度分析
chrome·python·chrome devtools
Dxy12393102166 小时前
Python项目打包成EXE完整教程(PyInstaller实战避坑)
开发语言·python
bamb006 小时前
一个项目带你入门AI应用开发01
python
0566466 小时前
Python康复训练——常用标准库
开发语言·python·学习