107 lines
4.1 KiB
Python
107 lines
4.1 KiB
Python
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)
|
||
|