1. 参数化几何模型批量重建

参数化几何模型批量重建 学习卡片

任务拆解:从尺寸表到可用的 CAE 中间格式

本案例要解决的核心问题是:同一拓扑的零件(例如一块带孔安装板)有 N 组尺寸组合,手工在 CAD 里逐个改参数、导出、命名既慢又容易出错。我们用脚本驱动 CAD 内核,把「尺寸表」作为唯一输入,批量重建几何并输出 STEP/IGES 等中间格式,最后用一组可判定的指标验证重建稳定性。

关键约束有三个:拓扑必须保持一致(孔数、特征顺序不变,只允许尺寸变化);参数必须来自外部表格(脚本不硬编码尺寸);输出必须可被 CAE 前处理直接读取(实体有效、单位正确、命名可追溯)。

整体数据流与对象关系

下图给出本案例的完整链路:尺寸表 → 参数校验 → 内核重建 → 几何有效性检查 → 中间格式输出 → 结果清单。注意「校验」和「有效性检查」是两个不同关卡,前者防脏数据进入内核,后者防坏几何流入 CAE。

尺寸表 (CSV) part_id, L, W, T d_hole, n_hole, ... 每行 = 一个变体 参数校验 范围 / 类型 / 必填 孔边距 ≥ 安全值 不通过 → 记录并跳过 CAD 内核重建 草图 → 拉伸 → 孔阵列 特征顺序固定 参数驱动尺寸 几何有效性检查 实体数 / 体积 > 0 面数 / 孔数一致 失败 → 标记异常 中间格式输出 STEP / IGES / Parasolid,单位 mm,文件名含 part_id 供 CAE 前处理直接读取 结果清单 成功 / 跳过 / 失败 含原因与耗时 校验失败 / 重建异常 → 记录原因,不中断整批 稳定性验证指标(每批次汇总) ① 重建成功率 = 成功数 / 总行数,目标 100%(失败必须可解释) ② 拓扑一致性:孔数、面数、实体数与基准模型一致 ③ 几何有效性:体积 > 0,无自相交,单位与坐标系正确 ④ 输出可读性:STEP 能被 CAE 前处理无报错导入

尺寸表与参数校验

尺寸表用 CSV 维护,第一行是列名,每行代表一个几何变体。脚本读取后先做校验,避免把非法尺寸送进内核导致崩溃或产生退化几何。

part_id,L,W,T,d_hole,n_hole_x,n_hole_y,edge_margin
P001,120,80,6,8,3,2,15
P002,150,90,8,10,4,2,18
P003,100,60,5,6,2,2,12
P004,200,120,10,12,5,3,20

校验规则示例:所有尺寸必须为正数;edge_margin 必须大于 d_hole/2;n_hole_x、n_hole_y 必须为 ≥1 的整数。任何一行不满足,就记录到结果清单并跳过,不中断整批。

脚本驱动内核重建的关键逻辑

下面给出一个可运行路径清晰的 Python 示例,使用 cadquery 作为 CAD 内核(也可替换为 FreeCAD/OpenCASCADE 绑定)。核心思路是:把建模过程封装成函数,尺寸全部来自参数,特征顺序固定。

import csv
import cadquery as cq

def build_plate(L, W, T, d_hole, nx, ny, margin):
    # 固定拓扑:矩形板 → 拉伸 → 孔阵列
    plate = cq.Workplane("XY").rect(L, W).extrude(T)
    # 孔位计算:在有效区域内均匀分布
    xs = [(-L/2 + margin) + i * (L - 2*margin) / (nx - 1) for i in range(nx)] if nx > 1 else [0]
    ys = [(-W/2 + margin) + j * (W - 2*margin) / (ny - 1) for j in range(ny)] if ny > 1 else [0]
    holes = [(x, y) for x in xs for y in ys]
    plate = plate.faces(">Z").workplane().pushPoints(holes).hole(d_hole)
    return plate

def validate(row):
    for k in ["L","W","T","d_hole","edge_margin"]:
        if float(row[k]) <= 0:
            return False, f"{k} 非正"
    if float(row["edge_margin"]) <= float(row["d_hole"]) / 2:
        return False, "边距不足"
    if int(row["n_hole_x"]) < 1 or int(row["n_hole_y"]) < 1:
        return False, "孔数非法"
    return True, ""

results = []
with open("sizes.csv") as f:
    for row in csv.DictReader(f):
        ok, msg = validate(row)
        if not ok:
            results.append((row["part_id"], "跳过", msg))
            continue
        try:
            solid = build_plate(
                float(row["L"]), float(row["W"]), float(row["T"]),
                float(row["d_hole"]), int(row["n_hole_x"]),
                int(row["n_hole_y"]), float(row["edge_margin"])
            )
            # 有效性检查
            vol = solid.val().Volume()
            if vol <= 0:
                results.append((row["part_id"], "失败", "体积非正"))
                continue
            cq.exporters.export(solid, f"out/{row['part_id']}.step")
            results.append((row["part_id"], "成功", f"V={vol:.1f}"))
        except Exception as e:
            results.append((row["part_id"], "失败", str(e)[:40]))

for r in results:
    print(r)

运行后会在 out/ 目录生成每个变体的 STEP 文件,同时打印结果清单。注意:build_plate 中孔位计算假设 nx>1 时均匀分布,nx=1 时居中;这是拓扑固定下的尺寸驱动,不改变特征类型。

结果判读与稳定性验证

批量跑完后,重点看三类结果:

  • 成功:STEP 已生成,体积为正,孔数与预期一致。
  • 跳过:尺寸表本身不合法,属于输入问题,修正 CSV 后重跑即可。
  • 失败:内核重建或导出异常,需要看具体报错,常见原因是孔位超出板面、孔直径过大导致自相交。

稳定性验证不靠“看起来没问题”,而靠可复现的检查:用 CAE 前处理导入 STEP,确认实体数、面数、单位;或写一段脚本读取 STEP 并统计体积与孔数,与尺寸表逐行比对。只要有一行对不上,就说明该变体重建不稳定,需要定位是参数问题还是建模逻辑问题。

建议把尺寸表、脚本、输出目录放在同一工程下,输出文件名严格使用 part_id,这样 CAE 前处理模板可以按文件名自动匹配,为后续批量前处理打好基础。