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()
相关推荐
不会飞的鲨鱼6 小时前
抖音验证码滑动轨迹原理(续)
javascript·爬虫·python
翔云 OCR API6 小时前
文档识别接口:赋能企业高效办公与加速信息的数字化转型
开发语言·人工智能·python·计算机视觉·ocr·语音识别
咕噜签名-铁蛋6 小时前
游戏搭建与云服务器:构建高效稳定的游戏运营架构
python
mofei121386 小时前
正则表达式高级用法指南
python·正则表达式·零宽断言·原子分组
ozyzo6 小时前
python--多继承
python
坐吃山猪7 小时前
Python命令行工具Click
linux·开发语言·python
那雨倾城7 小时前
用 YOLO Pose + Segmentation 在PiscCode构建“语义佛光”:一次实时视觉语义融合实验
图像处理·python·opencv·算法·yolo·计算机视觉·视觉检测
初九之潜龙勿用7 小时前
GMM NZ 全流程详解实战:FSDP MOE 训练加速
人工智能·pytorch·python