news 2026/2/23 17:29:56

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
DeformPointSet 基于控制网格(Control Mesh)的 3D 几何体形变

一:主要的知识点

1、说明

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

2、知识点纪要

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


二:代码及注释

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()
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/19 23:04:31

直播录制终极指南:如何用DouyinLiveRecorder轻松录制全网直播内容

直播录制终极指南:如何用DouyinLiveRecorder轻松录制全网直播内容 【免费下载链接】DouyinLiveRecorder 项目地址: https://gitcode.com/gh_mirrors/do/DouyinLiveRecorder 你是否曾经错过精彩的直播内容?或者想要保存喜欢的娱乐节目却不知道如何…

作者头像 李华
网站建设 2026/2/7 0:52:06

Joy-Con Toolkit终极指南:深度解析Switch手柄优化神器

Joy-Con Toolkit终极指南:深度解析Switch手柄优化神器 【免费下载链接】jc_toolkit Joy-Con Toolkit 项目地址: https://gitcode.com/gh_mirrors/jc/jc_toolkit 还在为Switch手柄的各种小问题烦恼吗?Joy-Con Toolkit就是你的救星!这款…

作者头像 李华
网站建设 2026/2/21 21:10:33

Zotero文献去重完全教程:一键清理重复条目的终极解决方案

还在为Zotero文献库中堆积如山的重复条目而头痛吗?当你从不同数据库导入文献时,同一篇文章经常被重复收录多次,这不仅浪费存储空间,还严重影响文献管理效率。ZoteroDuplicatesMerger插件就是专为解决这一问题而生的强大工具&#…

作者头像 李华
网站建设 2026/2/21 20:38:50

信息自由获取新方案:6款实用工具深度评测

信息自由获取新方案:6款实用工具深度评测 【免费下载链接】bypass-paywalls-chrome-clean 项目地址: https://gitcode.com/GitHub_Trending/by/bypass-paywalls-chrome-clean 在信息付费化浪潮席卷的今天,你是否经常遇到心仪的文章被付费墙阻挡在…

作者头像 李华
网站建设 2026/2/23 2:43:49

CCS安装实战:配置外部编辑器与版本控制集成

CCS开发效率跃迁:如何用VS Code和Git重构嵌入式工作流 你有没有过这样的经历?在CCS里写一段C代码,光标移动都卡顿;改完一个bug想回溯历史版本,却发现只能靠手动备份文件夹;团队协作时同事覆盖了你的修改&am…

作者头像 李华
网站建设 2026/2/19 18:41:22

LeagueAkari终极指南:英雄联盟自动化工具完全攻略

LeagueAkari终极指南:英雄联盟自动化工具完全攻略 【免费下载链接】LeagueAkari ✨兴趣使然的,功能全面的英雄联盟工具集。支持战绩查询、自动秒选等功能。基于 LCU API。 项目地址: https://gitcode.com/gh_mirrors/le/LeagueAkari 还在为错过匹…

作者头像 李华