| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- import os
- import vtk
- import pyvista as pv
- # -----------------------------------------------------------------------------
- # 1. 配置:要展示的文件夹路径(改成你自己的)
- # -----------------------------------------------------------------------------
- ROOT_FOLDER = r"./" # 示例:当前目录
- MAX_DEPTH = 3 # 限制深度,防止太密
- NODE_SPACING_X = 2.0
- NODE_SPACING_Y = 1.5
- # -----------------------------------------------------------------------------
- # 2. 递归遍历文件夹,生成树形结构数据
- # -----------------------------------------------------------------------------
- class TreeNode:
- def __init__(self, name, path, depth=0):
- self.name = name
- self.path = path
- self.depth = depth
- self.children = []
- self.x = 0.0
- self.y = 0.0
- def build_tree(folder, depth=0, max_depth=MAX_DEPTH):
- node = TreeNode(os.path.basename(folder) or folder, folder, depth)
- if depth >= max_depth:
- return node
- try:
- entries = sorted(os.listdir(folder))
- except PermissionError:
- return node
- for entry in entries:
- full = os.path.join(folder, entry)
- if os.path.isdir(full):
- child = build_tree(full, depth + 1, max_depth)
- node.children.append(child)
- return node
- # -----------------------------------------------------------------------------
- # 3. 树布局算法(简单层级横向布局)
- # -----------------------------------------------------------------------------
- def layout_tree(node: TreeNode, x=0.0, y=0.0):
- node.y = y
- node.x = x
- child_x = x - (len(node.children) - 1) * NODE_SPACING_X / 2
- for child in node.children:
- layout_tree(child, child_x, y - NODE_SPACING_Y)
- child_x += NODE_SPACING_X
- # -----------------------------------------------------------------------------
- # 4. 收集所有节点、边用于 VTK 绘制
- # -----------------------------------------------------------------------------
- def collect_geometry(node):
- points = []
- lines = []
- labels = []
- stack = [node]
- while stack:
- n = stack.pop()
- points.append([n.x, n.y, 0.0])
- labels.append(n.name)
- for child in n.children:
- points.append([child.x, child.y, 0.0])
- labels.append(child.name)
- lines.append(2) # 每个线段有两个点
- lines.append(len(points)-2) # 父节点的索引
- lines.append(len(points)-1) # 子节点的索引
- stack.append(child)
- return points, lines, labels
- # -----------------------------------------------------------------------------
- # 5. PyVista + VTK 绘制树
- # -----------------------------------------------------------------------------
- if __name__ == "__main__":
- tree = build_tree(ROOT_FOLDER)
- layout_tree(tree)
- points, lines, labels = collect_geometry(tree)
- # 构建点线云
- cloud = pv.PolyData(points)
- cloud.lines = lines
- cloud["label"] = labels
- # 绘图
- plotter = pv.Plotter(window_size=(1200, 800))
- plotter.add_mesh(cloud, color="#66ccff", point_size=12, render_lines_as_tubes=True, line_width=3)
- plotter.add_point_labels(cloud, "label", font_size=8, shape_color="white")
- plotter.add_text(
- f"Folder Tree: {ROOT_FOLDER}\nMax Depth: {MAX_DEPTH}",
- font_size=10, color="blue"
- )
- plotter.camera_position = "xy"
- plotter.show()
|