You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

提取PCB板框精确尺寸遇阻,寻求技术解决方法

解决PCB板框尺寸提取不准确的问题

核心问题分析

  • 板框所在层错误:你使用的Top.gbr是顶层铜箔层,板框通常单独存放在**机械层(GKO层)**或专门的Outline层,而非顶层铜箔层。
  • 坐标格式未解析:Gerber中的%FSLAX35Y35*%是坐标格式指令,代表X/Y采用3位整数+5位小数的格式,直接转float会导致数值错误。
  • 单位处理混乱:代码中手动/100再*1.36无依据,应根据Gerber开头的%MOMM*%(毫米)或%MOIN*%(英寸)自动处理单位。
  • 板框绘制方式不局限于G36/G37:多数PCB软件用G01(直线)绘制板框,并非必须使用G36/G37的Region命令。

修正后的Python代码

def parse_gerber_coordinate(value, format_spec):
    # 解析Gerber坐标格式,例:FSLAX35Y35 → X为3整数位+5小数位
    int_digits, frac_digits = format_spec
    sign = 1
    # 处理正负号
    if value.startswith('-'):
        sign = -1
        value = value[1:]
    elif value.startswith('+'):
        value = value[1:]
    # 补零至总长度(整数位+小数位)
    total_digits = int_digits + frac_digits
    value = value.zfill(total_digits)
    # 拆分整数与小数部分
    int_part = value[:int_digits] if int_digits > 0 else '0'
    frac_part = value[int_digits:] if frac_digits > 0 else '0'
    return sign * float(f"{int_part}.{frac_part}")

def extract_board_outline(gerber_file_path):
    board_outline = []
    parsing_outline = False
    coord_format = (3,5)  # 默认匹配FSLAX35Y35
    unit = 'mm'  # 默认毫米单位

    with open(gerber_file_path, 'r') as file:
        current_x = None
        current_y = None
        for line in file:
            line = line.strip().upper()
            if not line:
                continue
            # 读取单位设置
            if line == '%MOMM*%':
                unit = 'mm'
            elif line == '%MOIN*%':
                unit = 'inch'
            # 读取坐标格式
            if line.startswith('%FSLAX'):
                x_spec = line[5:7]
                y_spec = line[8:10]
                coord_format = (int(x_spec[0]), int(x_spec[1]))
            # 切换板框解析状态
            if 'G36' in line:
                parsing_outline = True
            elif 'G37' in line:
                parsing_outline = False
            # 提取坐标(支持G36/G37区域和G01直线绘制)
            if parsing_outline or line.startswith('G01'):
                if 'X' in line:
                    x_str = line.split('X')[1].split('Y')[0].split('D')[0].strip()
                    current_x = parse_gerber_coordinate(x_str, coord_format)
                if 'Y' in line:
                    y_str = line.split('Y')[1].split('D')[0].split('X')[0].strip()
                    current_y = parse_gerber_coordinate(y_str, coord_format)
                # 仅当X/Y都存在时添加坐标点
                if current_x is not None and current_y is not None:
                    board_outline.append((current_x, current_y))

    return board_outline, unit

def calculate_board_size(board_outline, unit):
    if not board_outline:
        return 0, 0, unit

    min_x = min(point[0] for point in board_outline)
    max_x = max(point[0] for point in board_outline)
    min_y = min(point[1] for point in board_outline)
    max_y = max(point[1] for point in board_outline)

    width = max_x - min_x
    height = max_y - min_y

    return width, height, unit

def main():
    # 替换为板框层Gerber文件路径,如outline.gbr、gko.gbr
    gerber_file_path = 'outline.gbr'
    board_outline, unit = extract_board_outline(gerber_file_path)

    if not board_outline:
        print("未找到板框,请确认文件是否为板框专用层(GKO/Outline)。")
    else:
        print("板框坐标:")
        for i, (x, y) in enumerate(board_outline, start=1):
            print(f"点{i}: X={x:.4f}, Y={y:.4f} {unit}")

        width, height, unit = calculate_board_size(board_outline, unit)
        print(f"\n板框尺寸:宽度={width:.4f} {unit}, 高度={height:.4f} {unit}")

if __name__ == "__main__":
    main()

关键修正说明

  • 层选择:必须使用板框专用层的Gerber文件,而非顶层铜箔层。
  • 坐标解析:新增parse_gerber_coordinate函数,严格遵循Gerber坐标格式规则解析数值。
  • 单位自动识别:从Gerber文件中读取单位指令,无需手动换算。
  • 多绘制方式支持:同时兼容G36/G37区域和G01直线绘制的板框。

额外注意事项

  • 若PCB使用G91(增量坐标)绘制板框,需添加G90/G91状态判断逻辑。
  • 若板框包含圆弧(G02/G03),需额外解析圆弧参数计算边界,当前代码仅支持直线板框。

内容的提问来源于stack exchange,提问作者Diogo Almeida

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 19:23:29