评论
Python批量查询dxf文件里面是有圆孔 ,钻孔,椭圆孔,并且在表格后面标注

Python批量查询dxf文件里面是有圆孔 ,钻孔,椭圆孔,并且在表格后面标注

我也不知道自己到底是什么时候释怀的,只是有天突然回过神来,好像一切都没那么重要了。那天之后我开始明白,我所谓的成长,其实是在乎的东西变少了。陌生人的认同不再那么重要,他人的声音变得无关紧要,喜欢的东西也不一定非要分享

缘起

由于不同设计师提供的dxf匿名规则不同导致,在某项目上需要手动检测2000+的dxf是否有钻孔

手动操作过程十分枯燥且浪费时间,况且图纸的排序和表格排序有出入;py这时候突然尤为的重要;Python批量查询dxf文件里面是有圆孔 ,钻孔,椭圆孔,并且在表格后面标注

ezdxf库

官方文档:

https://ezdxf.readthedocs.io/en/stable/introduction.html

ezdxf库是可以查询出dxf里面的信息情况的,本想通过打印实体获取圆孔就可以结束了

但是不知道是不是版本问题,打印出的实体 ,没有含有CIRCLE属性,一直是POLYLINE

Python批量查询dxf文件里面是有圆孔 ,钻孔,椭圆孔,并且在表格后面标注

案例

后面只能使用获取LINE,判断是否存在十字交点批量查询dxf文件里面是有圆孔 ,钻孔,椭圆孔

import ezdxf
import os
import math


# 判断是否为有孔
def check_crossing(file_path):
    doc = ezdxf.readfile(file_path)
    msp = doc.modelspace()

    for entity in msp:
        if entity.dxftype() == 'LINE':  # 只检查直线类型的实体
            start = entity.dxf.start
            end = entity.dxf.end
            line_length = math.sqrt((end[0] - start[0])**2 + (end[1] - start[1])**2)
            # 检查是否与其他直线存在十字交叉,且十字长度大于 52
            for other_entity in msp:
                if other_entity.dxftype() == 'LINE' and other_entity is not entity:
                    other_start = other_entity.dxf.start
                    other_end = other_entity.dxf.end
                    other_line_length = math.sqrt((other_end[0] - other_start[0])**2 + (other_end[1] - other_start[1])**2)
                    if are_lines_crossing(start, end, other_start, other_end):
                        return True  # 存在十字交叉且长度大于 52,返回 True

    return False  # 遍历完所有直线都没有找到符合条件的十字交叉,返回 False

# 判断是否为切孔
def check_crossing_52(file_path):
    doc = ezdxf.readfile(file_path)
    msp = doc.modelspace()

    for entity in msp:
        if entity.dxftype() == 'LINE':  # 只检查直线类型的实体
            start = entity.dxf.start
            end = entity.dxf.end
            line_length = math.sqrt((end[0] - start[0])**2 + (end[1] - start[1])**2)
            # 检查是否与其他直线存在十字交叉,且十字长度大于 52
            for other_entity in msp:
                if other_entity.dxftype() == 'LINE' and other_entity is not entity:
                    other_start = other_entity.dxf.start
                    other_end = other_entity.dxf.end
                    other_line_length = math.sqrt((other_end[0] - other_start[0])**2 + (other_end[1] - other_start[1])**2)
                    if are_lines_crossing(start, end, other_start, other_end) and (line_length > 52 and other_line_length > 52):
                        return True  # 存在十字交叉且长度大于 52,返回 True

    return False  # 遍历完所有直线都没有找到符合条件的十字交叉,返回 False

# 判断是否为椭圆孔
def check_crossing_not(file_path):
    doc = ezdxf.readfile(file_path)
    msp = doc.modelspace()

    for entity in msp:
        if entity.dxftype() == 'LINE':  # 只检查直线类型的实体
            start = entity.dxf.start
            end = entity.dxf.end
            line_length = math.sqrt((end[0] - start[0])**2 + (end[1] - start[1])**2)
            # 检查是否与其他直线存在十字交叉,且十字长度大于 52
            for other_entity in msp:
                if other_entity.dxftype() == 'LINE' and other_entity is not entity:
                    other_start = other_entity.dxf.start
                    other_end = other_entity.dxf.end
                    other_line_length = math.sqrt((other_end[0] - other_start[0])**2 + (other_end[1] - other_start[1])**2)
                    if are_lines_crossing(start, end, other_start, other_end) and (line_length != other_line_length):
                        return True  # 存在十字交叉且长度大于 52,返回 True

    return False  # 遍历完所有直线都没有找到符合条件的十字交叉,返回 False

def are_lines_crossing(start1, end1, start2, end2):
    # 使用向量叉积判断两条线段是否相交
    def cross_product(v1, v2):
        return v1[0] * v2[1] - v1[1] * v2[0]

    v1 = (end1[0] - start1[0], end1[1] - start1[1])
    v2 = (start2[0] - start1[0], start2[1] - start1[1])
    v3 = (end2[0] - start1[0], end2[1] - start1[1])

    cp1 = cross_product(v1, v2)
    cp2 = cross_product(v1, v3)

    if cp1 * cp2 <= 0:
        v4 = (start1[0] - start2[0], start1[1] - start2[1])
        v5 = (end1[0] - start2[0], end1[1] - start2[1])
        cp3 = cross_product(v4, v5)
        cp4 = cross_product(v4, v2)
        if cp3 * cp4 <= 0:
            return True  # 两条线段相交

    return False  # 两条线段不相交或仅端点相交

# 指定目录
directory = "抓图"

for root, dirs, files in os.walk(directory):
    for file in files:
        if file.endswith(".dxf"):
            file_path = os.path.join(root, file)
            if check_crossing(file_path):
                print(f"{file_path} 有孔")
                if check_crossing_52(file_path):
                    print(f"{file_path} 切孔")
                    if check_crossing_not(file_path):
                        print(f"{file_path} 椭圆孔")
Python批量查询dxf文件里面是有圆孔 ,钻孔,椭圆孔,并且在表格后面标注

表格标注

成功标志出dxf是否有圆孔后,需要再清单进行标注;需要用到pandas和openpyxl库

将得到编号存在txt中,并且去除编号外的文字内容,再通过txt和表格对比,若存在内容在后面第8列标注有孔


import pandas as pd

# # 读取 Excel 文件
df = pd.read_excel('star.xlsx')

# 读取 txt 文件
with open('zk.txt', 'r') as f:
    text_names = f.read().splitlines()

# 循环对比并标注
for index, name in enumerate(df.iloc[:, 0]):
    if name in text_names:
        df.iat[index, 8] = '有孔'  # 第九列的索引为 8

# 保存修改后的 Excel 文件
df.to_excel('new_excel_file.xlsx', index=False)

print(df.shape)
Python批量查询dxf文件里面是有圆孔 ,钻孔,椭圆孔,并且在表格后面标注

如果出现以下错误,说第8列没有内容,我们只需要在第8列中随意输入几个文字即可


IndexError: index 8 is out of bounds for axis 0 with size 7

末尾

我就是一个废物,80%的代码都是AI提供