用Python代码实现:21 输出 stl 模型至 vtk 文件并添加自定义单值属性【例】自定义属性为点坐标的 x 值。22 构建三角网格模型的半边Half Edge结构。23 基于半边结构完成网格模型的层次遍历 1 任选网格模型中的一点𝑝0 = 𝑥0 𝑦0 𝑧0 并将该点的单值属性记为 0;如:点列表中第一个点;x 值的极大或极小点;… …等等 2 基于半边结构从𝑝0出发寻找其邻接点?
由于题目中的内容较多,这里只提供部分可能的实现思路,具体实现需要根据需求进行修改和完善。
2.1 实现思路:
- 使用vtk模块读取stl文件,并将数据存储在vtkPolyData对象中。
- 使用vtk模块创建一个新的标量数据数组,用于存储自定义单值属性。
- 遍历vtkPolyData对象中的所有点,获取每个点的坐标,计算出自定义单值属性的值,并将其存储到标量数据数组中。
- 将标量数据数组添加到vtkPolyData对象中,并使用vtk模块将其写入vtk文件。
2.2 实现思路:
- 创建一个HalfEdge类,用于表示半边数据结构中的一条半边。
- 在HalfEdge类中定义各种操作函数,如获取半边的起始点、终止点、相邻半边等。
- 创建一个Mesh类,用于表示整个三角网格模型。
- 在Mesh类中定义各种操作函数,如添加顶点、添加面、构建半边数据结构等。
- 利用HalfEdge类和Mesh类中的操作函数,构建三角网格模型的半边数据结构。
2.3 实现思路:
- 在Mesh类中定义一个函数,用于实现“层次”遍历。
- 选择一个起始点p0,并将其单值属性记为0。
- 从p0出发,遍历其邻接点,并将其单值属性记为1。
- 从邻接点中的每个点出发,遍历其邻接点,并将其单值属性记为2。
- 重复上述步骤,直至遍历所有的网格顶点,并保存相应的单值属性。
- 最终将单值属性添加到vtk数据中,并写入vtk文件。
示例代码:
2.1:
import vtk
# 读取stl文件
reader = vtk.vtkSTLReader()
reader.SetFileName("C:/Users/13611/Desktop/人工智能实践4.24/STL-VTK/Bunny_STL.stl")
reader.Update()
# 获取点数据
points = reader.GetOutput().GetPoints()
# 创建标量数据数组
array = vtk.vtkDoubleArray()
array.SetName("CustomAttribute")
# 计算自定义单值属性
for i in range(points.GetNumberOfPoints()):
x, y, z = points.GetPoint(i)
custom_attr = x
array.InsertNextValue(custom_attr)
# 添加标量数据数组到vtk数据中
reader.GetOutput().GetPointData().AddArray(array)
# 写入vtk文件
writer = vtk.vtkDataSetWriter()
writer.SetFileName("output.vtk")
writer.SetInputData(reader.GetOutput())
writer.Update()
2.2:
class HalfEdge:
def __init__(self):
self.vertex = None # 起始顶点
self.pair = None # 对称半边
self.face = None # 所在面
self.next = None # 下一条半边
def set_vertex(self, vertex):
self.vertex = vertex
def set_pair(self, pair):
self.pair = pair
def set_face(self, face):
self.face = face
def set_next(self, next):
self.next = next
def get_vertex(self):
return self.vertex
def get_pair(self):
return self.pair
def get_face(self):
return self.face
def get_next(self):
return self.next
class Mesh:
def __init__(self):
self.vertices = [] # 顶点列表
self.faces = [] # 面列表
self.halfedges = [] # 半边列表
def add_vertex(self, x, y, z):
vertex = (x, y, z)
self.vertices.append(vertex)
def add_face(self, v1, v2, v3):
face = (v1, v2, v3)
self.faces.append(face)
# 添加半边
he1 = HalfEdge()
he2 = HalfEdge()
he3 = HalfEdge()
he1.set_vertex(v1)
he2.set_vertex(v2)
he3.set_vertex(v3)
he1.set_next(he2)
he2.set_next(he3)
he3.set_next(he1)
self.halfedges.append(he1)
self.halfedges.append(he2)
self.halfedges.append(he3)
def get_halfedge(self, v1, v2):
# 获取从v1到v2的半边
for he in self.halfedges:
if he.get_vertex() == v1 and he.get_next().get_vertex() == v2:
return he
return None
def build_halfedge_structure(self):
# 构造半边数据结构
for face in self.faces:
v1, v2, v3 = face
he1 = self.get_halfedge(v1, v2)
he2 = self.get_halfedge(v2, v3)
he3 = self.get_halfedge(v3, v1)
he1.set_pair(he3)
he2.set_pair(he1)
he3.set_pair(he2)
for he in [he1, he2, he3]:
if he.get_face() is None:
he.set_face(face)
def traverse(self):
# 实现“层次”遍历
start_vertex = 0
level = 0
visited = set()
visited.add(start_vertex)
# 将起始点的单值属性记为0
self.vertices[start_vertex].custom_attr = 0
queue = [(start_vertex, level)]
while len(queue) > 0:
vertex, level = queue.pop(0)
# 遍历邻接点
for he in self.halfedges:
if he.get_vertex() == vertex and he.get_pair() is not None:
neighbor = he.get_pair().get_vertex()
if neighbor not in visited:
visited.add(neighbor)
queue.append((neighbor, level + 1))
self.vertices[neighbor].custom_attr = level + 1
2.3:
import vtk
class HalfEdge:
...
class Mesh:
...
def traverse(self):
# 实现“层次”遍历
start_vertex = 0
level = 0
visited = set()
visited.add(start_vertex)
# 将起始点的单值属性记为0
self.vertices[start_vertex].custom_attr = 0
queue = [(start_vertex, level)]
while len(queue) > 0:
vertex, level = queue.pop(0)
# 遍历邻接点
for he in self.halfedges:
if he.get_vertex() == vertex and he.get_pair() is not None:
neighbor = he.get_pair().get_vertex()
if neighbor not in visited:
visited.add(neighbor)
queue.append((neighbor, level + 1))
self.vertices[neighbor].custom_attr = level + 1
# 读取stl文件,构建Mesh对象,构建半边数据结构
reader = vtk.vtkSTLReader()
reader.SetFileName("C:/Users/13611/Desktop/人工智能实践4.24/STL-VTK/Bunny_STL.stl")
reader.Update()
mesh = Mesh()
points = reader.GetOutput().GetPoints()
for i in range(points.GetNumberOfPoints()):
x, y, z = points.GetPoint(i)
mesh.add_vertex(x, y, z)
cells = reader.GetOutput().GetPolys()
for i in range(cells.GetNumberOfCells()):
cell = cells.GetCell(i)
v1, v2, v3 = cell.GetPointIds()
mesh.add_face(v1, v2, v3)
mesh.build_halfedge_structure()
# 进行“层次”遍历
mesh.traverse()
# 将单值属性添加到vtk数据中
array = vtk.vtkDoubleArray()
array.SetName("CustomAttribute")
for vertex in mesh.vertices:
custom_attr = vertex.custom_attr
array.InsertNextValue(custom_attr)
reader.GetOutput().GetPointData().AddArray(array)
# 写入vtk文件
writer = vtk.vtkDataSetWriter()
writer.SetFileName("output.vtk")
writer.SetInputData(reader.GetOutput())
writer.Update()
``
原文地址: https://www.cveoy.top/t/topic/eDOA 著作权归作者所有。请勿转载和采集!