import ezdxf import os import math import sys from ezdxf.math import Vec2 # --- 配置 --- # 将脚本的父目录(项目根目录)添加到Python路径中,以便正确解析模块 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) PROJECT_ROOT = os.path.dirname(SCRIPT_DIR) sys.path.append(PROJECT_ROOT) INPUT_DXF_NAME = "图签测试.dxf" OUTPUT_DXF_NAME = "图签测试_with_text.dxf" INPUT_DXF_PATH = os.path.join(SCRIPT_DIR, INPUT_DXF_NAME) # 确保输出目录存在 output_dir = os.path.join(PROJECT_ROOT, "04_Test_Files", "结果") os.makedirs(output_dir, exist_ok=True) OUTPUT_DXF_PATH = os.path.join(output_dir, OUTPUT_DXF_NAME) TARGET_COLOR = 5 # 蓝色 TARGET_LENGTH = 331.7 LENGTH_TOLERANCE = 1e-4 # 浮点数比较的容差 TEXT_CONTENT = "test2025" TEXT_HEIGHT = 8.0 # 适当调整文字高度 TEXT_OFFSET = 15.0 # 文字距离线的垂直距离 def add_text_above_specific_lines(input_path, output_path): """ 查找特定颜色和长度的线,并在其上方添加文字。 """ if not os.path.exists(input_path): print(f"错误: 输入的 DXF 文件未找到: '{input_path}'") return try: print(f"--- 开始处理文件: {os.path.basename(input_path)} ---") doc = ezdxf.readfile(input_path) msp = doc.modelspace() # 查询所有颜色为蓝色 (5) 的 LINE 实体 query = f'LINE[color=={TARGET_COLOR}]' blue_lines = msp.query(query) print(f"找到了 {len(blue_lines)} 条蓝色线段。现在开始根据长度进行筛选...") added_count = 0 for line in blue_lines: start = line.dxf.start end = line.dxf.end # 为了计算长度和角度,投影到2D平面 start_2d = Vec2(start.x, start.y) end_2d = Vec2(end.x, end.y) length = start_2d.distance(end_2d) # 检查长度是否在容差范围内匹配目标长度 if math.isclose(length, TARGET_LENGTH, rel_tol=LENGTH_TOLERANCE): print(f" -> 找到匹配线段: 长度={length:.4f}, 起点=({start.x:.2f}, {start.y:.2f})") # 计算3D中点 mid_point_3d = start.lerp(end, 0.5) # --- 使用 math.atan2 在2D平面上计算角度和偏移 --- delta = end_2d - start_2d if delta.magnitude > 1e-9: # 避免处理零长度的线段 # 使用 atan2 计算角度,更稳健 angle_rad = math.atan2(delta.y, delta.x) # 计算法线方向(逆时针旋转90度)的偏移向量 offset_vec_2d = Vec2.from_angle(angle_rad + math.pi / 2, TEXT_OFFSET) # 将2D偏移向量转换回3D (Z=0),并加到3D中点上,得到最终插入点 # .vec3 属性将 Vec2(x, y) 转换为 Vec3(x, y, 0) text_insert_point = mid_point_3d + offset_vec_2d.vec3 # 添加文字实体 msp.add_text( TEXT_CONTENT, dxfattribs={ 'height': TEXT_HEIGHT, 'color': 2, # 颜色设置为黄色(2),以便在CAD中清晰可见 } ).set_placement( text_insert_point, align=ezdxf.enums.TextEntityAlignment.BOTTOM_CENTER ) added_count += 1 if added_count > 0: doc.saveas(output_path) print(f"\n操作成功!在 {added_count} 条匹配的线段上方添加了文字。") print(f"修改后的文件已保存到: '{output_path}'") else: print(f"\n操作完成,但未找到任何颜色为蓝色且长度约为 {TARGET_LENGTH} 的线段。") except IOError: print(f"错误: 无法读取文件: '{input_path}'") except Exception as e: print(f"处理 DXF 文件时发生未知错误: {e}") if __name__ == "__main__": add_text_above_specific_lines(INPUT_DXF_PATH, OUTPUT_DXF_PATH)