Text-to-CAD 训练营 Day 2:参数化设计 - 构建标准件库
系列导航 | Day 1:Text-to-CAD 入门与环境搭建 | Day 2:参数化设计 | Day 3:装配体与约束 | Day 4:工程图与出图 | Day 5:综合项目实战
引言:从"画一个零件"到"定义一族零件"
在 Day 1 中,我们学会了用自然语言驱动 AI 生成单个 CAD 模型。但真正的工程实践中,机械设计从来不是从零开始的——工程师每天都在和标准件打交道:螺栓、螺母、垫圈、轴承、齿轮……这些零件有成百上千种规格,如果每个都从头建模,效率将极其低下。
参数化设计正是解决这个问题的核心方法论。通过定义一组参数和约束关系,我们可以用一个模型描述一整族零件。结合 AI 和 CadQuery,你只需要告诉 Claude:"帮我生成一个 M10x50 的六角头螺栓",几秒钟后就能得到精确的 3D 模型。

Day 2 的目标:掌握参数化设计思维,学会用 CadQuery 构建标准件库,实现"一次定义,批量生成"。
一、参数化设计深度解析
1.1 什么是参数化设计?
参数化设计(Parametric Design)是一种通过变量(参数)来控制几何形状的设计方法。与传统"直接建模"不同,参数化设计记录的是设计意图而非最终的几何数据。
1.2 参数驱动模型的优势
(1)设计效率倍增
一个参数化螺栓模型可以覆盖 M3 到 M30 的所有规格,只需修改直径参数。传统方法需要为每个规格单独建模。
(2)设计一致性保证
所有参数之间的数学关系(如螺栓头宽 = 1.5 x 直径)由代码保证,不会出现人工建模时的计算错误。
(3)便于版本管理和协作
参数以代码形式存储,天然支持 Git 版本控制,团队成员可以方便地协作和审查。
(4)与 AI 完美结合
Claude 等 AI 模型擅长理解参数关系和生成代码,参数化设计让 AI 的能力得到最大发挥。
1.3 参数间的关系与约束
参数化设计的核心在于建立参数之间的数学关系。以六角头螺栓为例:
螺纹直径 (d) ← 主参数(用户输入)螺距 (p) ← 由 d 查表得到头部高度 (k) ← k ≈ 0.6d(经验公式)头部对边宽度 (s) ← s ≈ 1.5d(经验公式)螺杆长度 (l) ← 主参数(用户输入)倒角尺寸 ← c ≈ p/4(经验公式)这些关系可以总结为三类约束:
• 查表约束:从标准表格中获取值(如螺距由直径查 GB/T 5782) • 公式约束:通过数学公式计算(如头部高度 = 0.6 x 直径) • 逻辑约束:条件判断(如直径 < 6mm 时不加工退刀槽)
1.4 设计意图的表达
参数化设计不仅仅是"用变量替代常量",更重要的是表达设计意图:
# 糟糕的参数化 - 只是替换了魔法数字head_height = 6.4 # 为什么是6.4?不知道# 好的参数化 - 表达了设计意图head_height = 0.64 * diameter # 头部高度约为直径的0.64倍(ISO标准)在 AI 辅助设计中,清晰的设计意图表达让 Claude 能够:
• 理解你想要什么,而不仅仅是你写了什么 • 在参数超出合理范围时给出警告 • 根据设计意图自动推导缺失的参数
二、标准件设计规范
2.1 常见标准件类型
机械设计中常见的标准件可以分为以下几大类:
标准件分类├── 紧固件 (Fasteners)│ ├── 螺栓 (Bolts) - 六角头、内六角、沉头等│ ├── 螺母 (Nuts) - 六角螺母、锁紧螺母等│ ├── 螺钉 (Screws) - 机螺钉、自攻螺钉等│ └── 垫圈 (Washers) - 平垫圈、弹簧垫圈等├── 传动件 (Transmission)│ ├── 齿轮 (Gears) - 直齿轮、斜齿轮、锥齿轮等│ ├── 轴承 (Bearings) - 深沟球轴承、圆锥滚子轴承等│ └── 联轴器 (Couplings)├── 轴系零件 (Shaft Components)│ ├── 键 (Keys) - 平键、花键等│ ├── 销 (Pins) - 圆柱销、圆锥销等│ └── 挡圈 (Retaining Rings)└── 密封件 (Seals) ├── O型圈 (O-rings) ├── 油封 (Oil Seals) └── 密封垫片 (Gaskets)2.2 标准参数查表方法
标准件的参数通常来自国家标准(GB)、国际标准(ISO)或企业标准。以下是常用的查表方法:
(1)在线标准查询
• 标准网 - 中国国家标准查询 • ISO 官网 - 国际标准
(2)机械设计手册
《机械设计手册》是最权威的纸质参考资料,包含所有常用标准件的完整参数表。
(3)在代码中建立参数字典
对于常用标准件,建议将参数表直接嵌入代码:
# GB/T 5782 六角头螺栓标准参数BOLT_STANDARDS = { "M3": {"pitch": 0.5, "head_h": 2.0, "head_s": 5.5, "head_d": 5.3}, "M4": {"pitch": 0.7, "head_h": 2.8, "head_s": 7.0, "head_d": 6.7}, "M5": {"pitch": 0.8, "head_h": 3.5, "head_s": 8.0, "head_d": 7.6}, "M6": {"pitch": 1.0, "head_h": 4.0, "head_s": 10.0, "head_d": 9.4}, "M8": {"pitch": 1.25, "head_h": 5.3, "head_s": 13.0, "head_d": 12.6}, "M10": {"pitch": 1.5, "head_h": 6.4, "head_s": 17.0, "head_d": 15.9}, "M12": {"pitch": 1.75, "head_h": 7.5, "head_s": 19.0, "head_d": 18.5}, "M16": {"pitch": 2.0, "head_h": 10.0, "head_s": 24.0, "head_d": 24.0}, "M20": {"pitch": 2.5, "head_h": 12.5, "head_s": 30.0, "head_d": 30.0},}2.3 公差与配合在参数化中的体现
在参数化设计中,公差信息同样可以参数化:
# 常用公差等级对应的偏差值(轴/孔)TOLERANCE_TABLE = { "H7": {"type": "hole", "deviations": {6: (0, 12), 10: (0, 15), 18: (0, 18)}}, "g6": {"type": "shaft", "deviations": {6: (-5, -14), 10: (-6, -17), 18: (-7, -20)}}, "k6": {"type": "shaft", "deviations": {6: (2, 11), 10: (2, 14), 18: (2, 17)}},}def get_tolerance(name, nominal_size): """根据公差等级和公称尺寸获取上下偏差(单位:微米)""" tol = TOLERANCE_TABLE[name] for size_limit in sorted(tol["deviations"].keys()): if nominal_size <= size_limit: return tol["deviations"][size_limit] raise ValueError(f"未找到公称尺寸 {nominal_size} 的公差数据")提示:在 CadQuery 中,公差主要影响导出 STEP 文件时的精度设置。对于需要精密配合的零件,建议在模型中直接使用极限尺寸建模。
三、实操练习 1:创建参数化螺栓
3.1 需求分析
我们要创建一个支持 M6/M8/M10/M12 四种规格的六角头螺栓,包含以下特征:
• 六角头(正六边形截面) • 螺杆(圆柱体) • 螺纹(简化表示或真实螺纹) • 倒角(头部端面倒角)
3.2 完整 CadQuery 代码
"""参数化六角头螺栓生成器支持规格:M6, M8, M10, M12标准参考:GB/T 5782-2016"""import cadquery as cqimport mathimport json# ============================================================# 螺栓标准参数表(GB/T 5782)# ============================================================BOLT_STANDARDS = { 6: { "name": "M6", "pitch": 1.0, # 螺距 (mm) "head_height": 4.0, # 头部高度 k (mm) "head_width": 10.0, # 头部对边宽度 s (mm) "thread_length": 18.0, # 螺纹长度 b (mm) "chamfer": 0.4, # 倒角尺寸 (mm) "washer_face": 0.5, # 支承面厚度 (mm) }, 8: { "name": "M8", "pitch": 1.25, "head_height": 5.3, "head_width": 13.0, "thread_length": 22.0, "chamfer": 0.5, "washer_face": 0.6, }, 10: { "name": "M10", "pitch": 1.5, "head_height": 6.4, "head_width": 17.0, "thread_length": 26.0, "chamfer": 0.6, "washer_face": 0.7, }, 12: { "name": "M12", "pitch": 1.75, "head_height": 7.5, "head_width": 19.0, "thread_length": 30.0, "chamfer": 0.7, "washer_face": 0.8, },}# ============================================================# 螺栓生成函数# ============================================================def create_hex_bolt(diameter: int, length: float, thread: bool = True) -> cq.Workplane: """ 创建参数化六角头螺栓 参数: diameter: 螺栓公称直径 (6, 8, 10, 12) length: 螺栓总长度 (mm) thread: 是否生成螺纹特征 (True=简化螺纹, False=光杆) 返回: CadQuery Workplane 对象 """ if diameter not in BOLT_STANDARDS: raise ValueError(f"不支持的螺栓规格: M{diameter},请选择 6, 8, 10, 12") params = BOLT_STANDARDS[diameter] d = diameter p = params["pitch"] k = params["head_height"] s = params["head_width"] b = min(params["thread_length"], length - 2 * p) # 螺纹长度不超过总长 c = params["chamfer"] print(f"正在生成螺栓: {params['name']}x{length}") print(f" 螺距: {p}mm, 头部高度: {k}mm, 对边宽度: {s}mm") # ---------------------------------------------------------- # 1. 创建六角头 # ---------------------------------------------------------- # 正六边形的外接圆半径 = 对边宽度 / (2 * cos(30°)) hex_radius = (s / 2) / math.cos(math.pi / 6) head = ( cq.Workplane("XY") .polygon(6, hex_radius) .extrude(k) ) # 头部顶面倒角(使六角头顶部略带锥度,更真实) head = head.faces(">Z").chamfer(c * 0.5) # ---------------------------------------------------------- # 2. 创建螺杆 # ---------------------------------------------------------- shaft = ( cq.Workplane("XY") .workplane(offset=k) .circle(d / 2) .extrude(length) ) # ---------------------------------------------------------- # 3. 合并头部和螺杆 # ---------------------------------------------------------- bolt = head.union(shaft) # ---------------------------------------------------------- # 4. 螺杆端面倒角 # ---------------------------------------------------------- bolt = bolt.faces("<Z").chamfer(c) # ---------------------------------------------------------- # 5. 生成螺纹(简化表示 - 螺旋线切割) # ---------------------------------------------------------- if thread and b > 0: thread_start = length - b thread_radius = d / 2 - 0.1 * p # 螺纹小径 # 创建螺纹区域(用螺旋槽简化表示) thread_section = ( cq.Workplane("XY") .workplane(offset=k + thread_start) .circle(d / 2) .extrude(b) ) # 在螺纹区域创建螺旋切割槽 num_turns = int(b / p) for i in range(num_turns): z_pos = k + thread_start + i * p + p / 2 # 创建一个小的螺旋截面切割 groove = ( cq.Workplane("XY") .workplane(offset=z_pos) .moveTo(d / 2 + 0.01, 0) .threePointArc( (d / 2 + 0.01, p * 0.15), (d / 2 + 0.01, p * 0.3) ) .extrude(0.1, both=True) ) # 注意:简化螺纹表示,实际应用中可使用 IScrew 脚本生成真实螺纹 # ---------------------------------------------------------- # 6. 头部下方的支承面过渡 # ---------------------------------------------------------- bolt = bolt.edges( cq.selectors.NearestToPointSelector((s / 4, 0, k)) ).fillet(0.3) return bolt# ============================================================# 主程序:生成四种规格的螺栓# ============================================================if __name__ == "__main__": # 生成 M6x30 螺栓 bolt_m6 = create_hex_bolt(diameter=6, length=30) cq.exporters.export(bolt_m6, "bolt_M6x30.step") # 生成 M8x40 螺栓 bolt_m8 = create_hex_bolt(diameter=8, length=40) cq.exporters.export(bolt_m8, "bolt_M8x40.step") # 生成 M10x50 螺栓 bolt_m10 = create_hex_bolt(diameter=10, length=50) cq.exporters.export(bolt_m10, "bolt_M10x50.step") # 生成 M12x60 螺栓 bolt_m12 = create_hex_bolt(diameter=12, length=60) cq.exporters.export(bolt_m12, "bolt_M12x60.step") print("\n所有螺栓模型已生成完毕!") print("输出文件: bolt_M6x30.step, bolt_M8x40.step, bolt_M10x50.step, bolt_M12x60.step")3.3 Claude Code 交互示例
在 Claude Code 中,你可以这样与 AI 交互来生成螺栓:
> 帮我创建一个 M10x50 的六角头螺栓,参考 GB/T 5782 标准,> 使用 CadQuery,包含六角头、螺杆和倒角特征。Claude: 好的,我来为你创建一个 M10x50 的六角头螺栓。根据 GB/T 5782 标准,M10 螺栓的参数如下:- 螺距: 1.5mm- 头部高度: 6.4mm- 对边宽度: 17mm[生成完整代码...]> 螺栓看起来不错,请把头部倒角改小一点,改为 0.3mm,> 并在螺杆末端也加上倒角。Claude: 好的,我来修改倒角参数...[修改代码并重新生成]
四、实操练习 2:创建参数化齿轮
4.1 渐开线直齿轮原理
渐开线齿轮是机械传动中最常用的齿轮类型。其齿廓曲线为渐开线(Involute),具有传动平稳、中心距可分等优点。
核心参数计算公式:
其中:
• m(模数):决定齿轮齿的大小,模数越大齿越大 • z(齿数):决定齿轮的大小,齿数越多分度圆越大 • alpha(压力角):标准值为 20°,影响齿廓形状
4.2 完整 CadQuery 齿轮代码
"""参数化渐开线直齿轮生成器支持自定义模数、齿数、压力角、齿宽、轴孔直径"""import cadquery as cqimport math# ============================================================# 齿轮参数类# ============================================================class GearParams: """齿轮参数定义""" def __init__( self, module: float = 2.0, # 模数 teeth: int = 20, # 齿数 pressure_angle: float = 20, # 压力角 (度) width: float = 15.0, # 齿宽 (mm) bore_diameter: float = 10.0, # 轴孔直径 (mm) hub_diameter: float = 0.0, # 轮毂直径 (0=自动计算) hub_height: float = 0.0, # 轮毂高度 (0=与齿宽相同) num_spokes: int = 0, # 辐条数量 (0=实心) spoke_width: float = 5.0, # 辐条宽度 (mm)): self.module = module self.teeth = teeth self.pressure_angle = math.radians(pressure_angle) self.width = width self.bore_diameter = bore_diameter # 自动计算轮毂直径(默认为轴孔直径的1.5倍) self.hub_diameter = hub_diameter if hub_diameter > 0 else bore_diameter * 1.5 self.hub_height = hub_height if hub_height > 0 else width self.num_spokes = num_spokes self.spoke_width = spoke_width # 计算齿轮几何参数 self._calculate_geometry() def _calculate_geometry(self): """计算齿轮几何参数""" m = self.module z = self.teeth alpha = self.pressure_angle self.pitch_diameter = m * z # 分度圆直径 self.tip_diameter = m * (z + 2) # 齿顶圆直径 self.root_diameter = m * (z - 2.5) # 齿根圆直径 self.base_diameter = self.pitch_diameter * math.cos(alpha) # 基圆直径 self.addendum = m # 齿顶高 self.dedendum = 1.25 * m # 齿根高 self.circular_pitch = math.pi * m # 齿距 self.tooth_thickness = self.circular_pitch / 2 # 齿厚 print(f"齿轮参数计算结果:") print(f" 分度圆直径: {self.pitch_diameter:.2f} mm") print(f" 齿顶圆直径: {self.tip_diameter:.2f} mm") print(f" 齿根圆直径: {self.root_diameter:.2f} mm") print(f" 基圆直径: {self.base_diameter:.2f} mm") def involute(self, t: float) -> tuple: """ 计算渐开线上的点 t: 展开角参数 (从基圆开始展开的角度) 返回: (x, y) 坐标 """ rb = self.base_diameter / 2 x = rb * (math.cos(t) + t * math.sin(t)) y = rb * (math.sin(t) - t * math.cos(t)) return (x, y)# ============================================================# 齿轮生成函数# ============================================================def create_spur_gear(params: GearParams) -> cq.Workplane: """ 创建渐开线直齿轮 参数: params: GearParams 齿轮参数对象 返回: CadQuery Workplane 对象 """ m = params.module z = params.teeth alpha = params.pressure_angle rb = params.base_diameter / 2 rt = params.tip_diameter / 2 rf = params.root_diameter / 2 rp = params.pitch_diameter / 2 # ---------------------------------------------------------- # 1. 生成齿廓曲线 # ---------------------------------------------------------- # 计算渐开线在齿顶圆处的展开角 inv_alpha = math.tan(alpha) - alpha # 渐开线函数 inv_tip = math.acos(rb / rt) tip_angle = math.tan(inv_tip) - inv_tip # 齿厚对应的半角 tooth_half_angle = params.tooth_thickness / (2 * rp) # 生成单个齿的轮廓点 tooth_points = [] # 齿根圆弧起点 tooth_points.append((rf, 0)) # 渐开线上升段(从基圆到齿顶) num_points = 20 for i in range(num_points + 1): t = tip_angle * i / num_points x, y = params.involute(t) tooth_points.append((x, y)) # 齿顶圆弧 tip_angle_span = (2 * math.pi / z) - 2 * tooth_half_angle for i in range(5): angle = tooth_half_angle + tip_angle_span * i / 4 x = rt * math.cos(angle) y = rt * math.sin(angle) tooth_points.append((x, y)) # 渐开线下降段(从齿顶到基圆)- 镜像 for i in range(num_points, -1, -1): t = tip_angle * i / num_points x, y = params.involute(t) # 镜像到齿的另一侧 mirror_angle = 2 * math.pi / z mx = x * math.cos(mirror_angle) - y * math.sin(mirror_angle) my = x * math.sin(mirror_angle) + y * math.cos(mirror_angle) tooth_points.append((mx, my)) # ---------------------------------------------------------- # 2. 构建齿轮截面 # ---------------------------------------------------------- gear_profile = cq.Workplane("XY") # 使用极坐标方式构建齿轮轮廓 # 先创建齿根圆 gear_profile = gear_profile.circle(rt + 1) # 逐个添加齿 for i in range(z): angle_offset = 2 * math.pi * i / z rotated_points = [] for (px, py) in tooth_points: rx = px * math.cos(angle_offset) - py * math.sin(angle_offset) ry = px * math.sin(angle_offset) + py * math.cos(angle_offset) rotated_points.append((rx, ry)) # 创建单个齿的拉伸体 tooth = ( cq.Workplane("XY") .polyline(rotated_points) .close() .extrude(params.width) ) if i == 0: gear_body = tooth else: gear_body = gear_body.union(tooth) # 创建齿轮主体(齿根圆柱) gear_body = ( cq.Workplane("XY") .circle(rf) .extrude(params.width) .union(gear_body) ) # ---------------------------------------------------------- # 3. 添加轮毂和轴孔 # ---------------------------------------------------------- # 轮毂 if params.hub_diameter > params.bore_diameter: hub = ( cq.Workplane("XY") .circle(params.hub_diameter / 2) .extrude(params.hub_height) ) gear_body = gear_body.union(hub) # 轴孔 gear_body = ( gear_body .faces(">Z") .workplane() .circle(params.bore_diameter / 2) .cutThruAll() ) # ---------------------------------------------------------- # 4. 添加辐条(如果需要) # ---------------------------------------------------------- if params.num_spokes > 0: spoke_area = ( cq.Workplane("XY") .circle(params.hub_diameter / 2) .extrude(params.width) ) for i in range(params.num_spokes): angle = 2 * math.pi * i / params.num_spokes spoke = ( cq.Workplane("XY") .transformed(rotate=(0, 0, math.degrees(angle))) .center(0, (params.hub_diameter + rf) / 4) .rect(params.spoke_width, (rf - params.hub_diameter) / 2) .extrude(params.width) ) spoke_area = spoke_area.union(spoke) gear_body = gear_body.intersect(spoke_area) # ---------------------------------------------------------- # 5. 倒角处理 # ---------------------------------------------------------- # 齿顶倒角 gear_body = gear_body.edges(">Z and |Z").chamfer(0.2 * m) return gear_body# ============================================================# 主程序# ============================================================if __name__ == "__main__": # 示例 1: 标准直齿轮 m=2, z=20 gear1_params = GearParams( module=2.0, teeth=20, pressure_angle=20, width=15.0, bore_diameter=10.0, ) gear1 = create_spur_gear(gear1_params) cq.exporters.export(gear1, "gear_m2_z20.step") print("\n齿轮 1 (m=2, z=20) 已生成: gear_m2_z20.step") # 示例 2: 大齿轮 m=3, z=40 gear2_params = GearParams( module=3.0, teeth=40, pressure_angle=20, width=20.0, bore_diameter=15.0, num_spokes=5, spoke_width=8.0, ) gear2 = create_spur_gear(gear2_params) cq.exporters.export(gear2, "gear_m3_z40.step") print("齿轮 2 (m=3, z=40, 5辐条) 已生成: gear_m3_z40.step") # 示例 3: 小齿轮 m=1.5, z=12 gear3_params = GearParams( module=1.5, teeth=12, pressure_angle=20, width=10.0, bore_diameter=6.0, ) gear3 = create_spur_gear(gear3_params) cq.exporters.export(gear3, "gear_m1.5_z12.step") print("齿轮 3 (m=1.5, z=12) 已生成: gear_m1.5_z12.step")4.3 Claude Code 交互示例:齿轮设计对话
以下是一个与 Claude Code 交互设计齿轮的完整对话示例:
> 我需要一个渐开线直齿轮,模数2,齿数30,压力角20度,> 齿宽20mm,轴孔直径12mm。请用 CadQuery 生成。Claude: 好的,我来为你创建这个齿轮。首先计算关键参数:- 分度圆直径: 2 x 30 = 60mm- 齿顶圆直径: 2 x (30+2) = 64mm- 齿根圆直径: 2 x (30-2.5) = 55mm- 基圆直径: 60 x cos(20°) = 56.38mm[生成齿轮代码...]> 齿轮看起来不错,但我需要加上键槽,宽度4mm,深度2mm,> 并且在轮毂处加一个直径20mm的凸台,高度25mm。Claude: 好的,我来添加键槽和轮毂凸台。键槽参数:宽4mm,深2mm(从轴孔表面算起)轮毂凸台:直径20mm,高度25mm(比齿宽多5mm)[修改代码,添加键槽和凸台特征...]> 请再帮我生成一个与之啮合的小齿轮,传动比为2:1,> 中心距需要精确保证。Claude: 传动比 2:1 意味着小齿轮齿数为 15。中心距 = (30 + 15) / 2 x 2 = 45mm小齿轮参数:- 模数: 2(必须相同才能啮合)- 齿数: 15- 压力角: 20°(必须相同)- 分度圆直径: 30mm[生成小齿轮代码,并创建装配体验证啮合...]
五、实操练习 3:建立标准件库
5.1 标准件库文件夹结构
一个良好的标准件库应该有清晰的目录结构和命名规范:
standard_parts_library/├── README.md # 库说明文档├── config/│ ├── bolt_standards.json # 螺栓标准参数│ ├── nut_standards.json # 螺母标准参数│ ├── gear_standards.json # 齿轮标准参数│ └── bearing_standards.json # 轴承标准参数├── fasteners/ # 紧固件│ ├── bolts/ # 螺栓│ │ ├── hex_bolt.py # 六角头螺栓生成器│ │ ├── socket_bolt.py # 内六角螺栓生成器│ │ └── carriage_bolt.py # 马车螺栓生成器│ ├── nuts/ # 螺母│ │ ├── hex_nut.py # 六角螺母生成器│ │ ├── lock_nut.py # 锁紧螺母生成器│ │ └── wing_nut.py # 蝶形螺母生成器│ └── washers/ # 垫圈│ ├── flat_washer.py # 平垫圈生成器│ └── spring_washer.py # 弹簧垫圈生成器├── transmission/ # 传动件│ ├── gears/ # 齿轮│ │ ├── spur_gear.py # 直齿轮生成器│ │ ├── helical_gear.py # 斜齿轮生成器│ │ └── bevel_gear.py # 锥齿轮生成器│ └── bearings/ # 轴承│ ├── deep_groove_bearing.py # 深沟球轴承│ └── taper_roller_bearing.py # 圆锥滚子轴承├── shafts/ # 轴系零件│ ├── plain_shaft.py # 光轴生成器│ ├── stepped_shaft.py # 阶梯轴生成器│ ├── key.py # 平键生成器│ └── retaining_ring.py # 挡圈生成器├── output/ # 输出目录│ ├── step/ # STEP 文件│ └── stl/ # STL 文件└── scripts/ # 工具脚本 ├── batch_generate.py # 批量生成脚本 └── library_browser.py # 库浏览器5.2 JSON 配置文件管理参数
将标准件参数从代码中分离到 JSON 配置文件,便于管理和更新:
config/bolt_standards.json:
{ "standard": "GB/T 5782-2016", "description": "六角头螺栓 - A级和B级", "units": "mm", "bolts": { "M3": { "pitch": 0.5, "head_height": 2.0, "head_width_across_flats": 5.5, "head_width_across_corners": 6.01, "thread_length": { "short": 12, "long": 18 }, "lengths": [8, 10, 12, 16, 20, 25, 30] }, "M6": { "pitch": 1.0, "head_height": 4.0, "head_width_across_flats": 10.0, "head_width_across_corners": 10.93, "thread_length": { "short": 18, "long": 24 }, "lengths": [12, 16, 20, 25, 30, 35, 40, 45, 50, 55, 60] }, "M8": { "pitch": 1.25, "head_height": 5.3, "head_width_across_flats": 13.0, "head_width_across_corners": 14.2, "thread_length": { "short": 22, "long": 28 }, "lengths": [16, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 80] }, "M10": { "pitch": 1.5, "head_height": 6.4, "head_width_across_flats": 17.0, "head_width_across_corners": 18.48, "thread_length": { "short": 26, "long": 32 }, "lengths": [20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 80, 90, 100] }, "M12": { "pitch": 1.75, "head_height": 7.5, "head_width_across_flats": 19.0, "head_width_across_corners": 20.58, "thread_length": { "short": 30, "long": 36 }, "lengths": [25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 80, 90, 100, 110, 120] } }}config/gear_standards.json:
{ "standard": "ISO 1328-1:2014", "description": "渐开线圆柱齿轮精度标准", "units": "mm", "standard_modules": [0.5, 0.8, 1.0, 1.25, 1.5, 2.0, 2.5, 3.0, 4.0, 5.0], "standard_pressure_angles": [14.5, 20, 25], "default_pressure_angle": 20, "gears": { "small": { "module": 1.5, "teeth": 12, "pressure_angle": 20, "width": 10, "bore": 6, "description": "小齿轮 - 高速传动" }, "medium": { "module": 2.0, "teeth": 20, "pressure_angle": 20, "width": 15, "bore": 10, "description": "中齿轮 - 通用传动" }, "large": { "module": 3.0, "teeth": 40, "pressure_angle": 20, "width": 20, "bore": 15, "description": "大齿轮 - 低速大扭矩" } }}5.3 配置加载工具
创建一个通用的配置加载工具:
"""标准件库配置加载工具"""import jsonimport osfrom pathlib import Pathfrom typing import Dict, Anyclass ConfigLoader: """标准件参数配置加载器""" def __init__(self, config_dir: str = "config"): self.config_dir = Path(config_dir) self._cache: Dict[str, Dict[str, Any]] = {} def load(self, filename: str) -> Dict[str, Any]: """ 加载 JSON 配置文件 参数: filename: 配置文件名 (如 "bolt_standards.json") 返回: 配置字典 """ if filename in self._cache: return self._cache[filename] filepath = self.config_dir / filename if not filepath.exists(): raise FileNotFoundError(f"配置文件不存在: {filepath}") with open(filepath, "r", encoding="utf-8") as f: config = json.load(f) self._cache[filename] = config print(f"已加载配置: {filename}") return config def get_bolt_params(self, spec: str) -> Dict[str, Any]: """获取螺栓参数 (如 "M10")""" config = self.load("bolt_standards.json") if spec not in config["bolts"]: available = ", ".join(config["bolts"].keys()) raise ValueError(f"未知规格: {spec},可用规格: {available}") return config["bolts"][spec] def get_gear_params(self, name: str) -> Dict[str, Any]: """获取齿轮参数 (如 "medium")""" config = self.load("gear_standards.json") if name not in config["gears"]: available = ", ".join(config["gears"].keys()) raise ValueError(f"未知齿轮类型: {name},可用类型: {available}") return config["gears"][name] def list_standards(self, category: str) -> list: """列出某类标准件的所有可用规格""" config = self.load(f"{category}_standards.json") return list(config.get(category, {}).keys())# 使用示例if __name__ == "__main__": loader = ConfigLoader("config") # 查看所有螺栓规格 print("可用螺栓规格:", loader.list_standards("bolt")) # 获取 M10 螺栓参数 m10_params = loader.get_bolt_params("M10") print(f"M10 螺栓参数: {json.dumps(m10_params, indent=2)}") # 获取中号齿轮参数 medium_gear = loader.get_gear_params("medium") print(f"中号齿轮参数: {json.dumps(medium_gear, indent=2)}")六、参数化设计模式
6.1 配置文件驱动的参数化设计
将参数化设计提升到新的层次——配置驱动。设计师只需编辑 JSON 文件,无需修改代码:
"""配置驱动的螺栓生成器从 JSON 配置文件读取参数,自动生成螺栓模型"""import cadquery as cqimport mathimport jsonfrom pathlib import Pathdef generate_bolt_from_config(config_path: str, output_dir: str = "output/step"): """ 从配置文件批量生成螺栓 参数: config_path: JSON 配置文件路径 output_dir: 输出目录 """ # 加载配置 with open(config_path, "r", encoding="utf-8") as f: config = json.load(f) # 确保输出目录存在 Path(output_dir).mkdir(parents=True, exist_ok=True) # 遍历所有规格 for spec, params in config["bolts"].items(): for length in params["lengths"]: bolt = _create_bolt(params, length) filename = f"{config['standard'].replace('/', '_')}_{spec}x{length}.step" filepath = Path(output_dir) / filename cq.exporters.export(bolt, str(filepath)) print(f" 已生成: {filename}")def _create_bolt(params: dict, length: float) -> cq.Workplane: """根据参数创建螺栓""" d = float(params.get("nominal_diameter", spec_to_diameter(params))) p = params["pitch"] k = params["head_height"] s = params["head_width_across_flats"] hex_radius = (s / 2) / math.cos(math.pi / 6) head = ( cq.Workplane("XY") .polygon(6, hex_radius) .extrude(k) ) shaft = ( cq.Workplane("XY") .workplane(offset=k) .circle(d / 2) .extrude(length) ) bolt = head.union(shaft) bolt = bolt.edges("|Z").chamfer(p / 4) return boltdef spec_to_diameter(params: dict) -> float: """从规格字符串提取直径数值""" # 简化实现,实际应从规格名解析 return 6.0 # 默认值if __name__ == "__main__": generate_bolt_from_config("config/bolt_standards.json") print("所有螺栓已批量生成!")6.2 设计模式总结
| 参数字典模式 | |||
| JSON配置模式 | |||
| 类封装模式 | |||
| 模板方法模式 |
七、自动化批量处理
7.1 批量生成螺栓
"""批量螺栓生成脚本自动生成所有规格和长度的组合"""import cadquery as cqimport mathimport jsonfrom pathlib import Pathfrom concurrent.futures import ProcessPoolExecutorimport timedef create_bolt(diameter: int, length: float, params: dict) -> cq.Workplane: """创建单个螺栓""" p = params["pitch"] k = params["head_height"] s = params["head_width"] hex_radius = (s / 2) / math.cos(math.pi / 6) head = cq.Workplane("XY").polygon(6, hex_radius).extrude(k) shaft = cq.Workplane("XY").workplane(offset=k).circle(diameter / 2).extrude(length) bolt = head.union(shaft) bolt = bolt.edges("|Z").chamfer(p / 4) return boltdef batch_generate_bolts(output_dir: str = "output/bolts"): """批量生成所有规格的螺栓""" bolt_standards = { 6: {"pitch": 1.0, "head_height": 4.0, "head_width": 10.0}, 8: {"pitch": 1.25, "head_height": 5.3, "head_width": 13.0}, 10: {"pitch": 1.5, "head_height": 6.4, "head_width": 17.0}, 12: {"pitch": 1.75, "head_height": 7.5, "head_width": 19.0}, } # 每种规格的常用长度 length_ranges = { 6: [20, 25, 30, 35, 40, 50], 8: [25, 30, 35, 40, 50, 60], 10: [30, 35, 40, 45, 50, 60, 70, 80], 12: [40, 45, 50, 55, 60, 70, 80, 90, 100], } Path(output_dir).mkdir(parents=True, exist_ok=True) total = 0 start_time = time.time() for diameter, params in bolt_standards.items(): for length in length_ranges[diameter]: bolt = create_bolt(diameter, length, params) filename = f"bolt_M{diameter}x{length}.step" filepath = Path(output_dir) / filename cq.exporters.export(bolt, str(filepath)) total += 1 print(f" [{total}] 已生成: {filename}") elapsed = time.time() - start_time print(f"\n批量生成完成!共 {total} 个螺栓,耗时 {elapsed:.1f} 秒")if __name__ == "__main__": batch_generate_bolts()7.2 批量生成齿轮
"""批量齿轮生成脚本生成不同模数和齿数组合的齿轮"""import cadquery as cqimport mathfrom pathlib import Pathdef batch_generate_gears(output_dir: str = "output/gears"): """批量生成齿轮系列""" # 模数序列 modules = [1.0, 1.5, 2.0, 2.5, 3.0] # 每种模数对应的齿数范围 teeth_ranges = { 1.0: [12, 16, 20, 24, 30], 1.5: [12, 16, 20, 24, 30, 36], 2.0: [12, 16, 20, 24, 30, 36, 40], 2.5: [16, 20, 24, 30, 36, 40, 48], 3.0: [16, 20, 24, 30, 36, 40, 48, 60], } # 标准轴孔直径 bore_map = { 1.0: 5.0, 1.5: 6.0, 2.0: 8.0, 2.5: 10.0, 3.0: 12.0, } Path(output_dir).mkdir(parents=True, exist_ok=True) total = 0 for m in modules: for z in teeth_ranges[m]: # 齿宽根据模数确定 width = max(8, int(m * 6)) # 计算齿轮参数 pitch_d = m * z tip_d = m * (z + 2) root_d = m * (z - 2.5) print(f" 生成齿轮: m={m}, z={z}, d={pitch_d}mm") # 创建简化齿轮模型 gear = _create_simple_gear(m, z, width, bore_map[m]) filename = f"gear_m{m}_z{z}.step" filepath = Path(output_dir) / filename cq.exporters.export(gear, str(filepath)) total += 1 print(f"\n批量生成完成!共 {total} 个齿轮")def _create_simple_gear(module, teeth, width, bore): """创建简化齿轮模型(用于批量生成)""" pitch_r = module * teeth / 2 tip_r = module * (teeth + 2) / 2 root_r = module * (teeth - 2.5) / 2 # 齿轮主体 gear = cq.Workplane("XY").circle(tip_r).extrude(width) # 齿根圆以下的凹槽(减重) if pitch_r > 20: gear = ( gear .faces(">Z") .workplane() .circle(root_r - 2) .cutBlind(-width + 2) ) # 轴孔 gear = ( gear .faces(">Z") .workplane() .circle(bore / 2) .cutThruAll() ) return gearif __name__ == "__main__": batch_generate_gears()7.3 批量处理最佳实践
1. 文件命名规范:使用 {类型}_{规格1}_{规格2}.step格式,如bolt_M10x50.step2. 输出目录组织:按类型分子目录,如 output/bolts/、output/gears/3. 日志记录:记录每个文件的生成时间和参数 4. 错误处理:单个文件生成失败不应中断整个批处理 5. 并行处理:大量文件时可使用多进程加速
八、效果验证
8.1 模型验证清单
生成标准件模型后,应进行以下验证:
•尺寸验证:关键尺寸是否符合标准参数表 •几何完整性:模型是否有破面、自交叉等缺陷 •特征完整性:倒角、圆角、孔等特征是否正确 •导出验证:STEP/STL 文件能否在其他 CAD 软件中正确打开 •装配验证:配合件能否正确装配(如螺栓能否穿过孔)
8.2 在线验证工具
• Zoo 在线查看器 - 上传 STEP 文件在线预览 • CadQuery Viewer - 使用 CadQuery 内置的查看功能 • FreeCAD - 免费开源 CAD 软件,支持 STEP 导入
8.3 使用 CadQuery 内置查看器
# 在 Jupyter Notebook 或 CQ-editor 中查看模型import cadquery as cqfrom jupyter_cadquery import show, PartGroup, Part# 生成螺栓bolt = create_hex_bolt(diameter=10, length=50)# 在 Jupyter 中显示show(bolt, name="M10x50 Bolt")
九、Day 2 作业
作业 1:参数化螺母(必做)
创建一个与螺栓配套的参数化六角螺母,支持 M6/M8/M10/M12 四种规格。
要求:
• 包含六角外形、螺纹孔、倒角 • 参数从 JSON 配置文件读取 • 生成 STEP 文件
参考参数:
作业 2:参数化平垫圈(必做)
创建一个参数化平垫圈,支持多种规格。
要求:
• 内孔直径、外圆直径、厚度均可参数化 • 参考 GB/T 97.1 标准
作业 3:标准件库扩展(选做)
在标准件库中添加以下零件:
• 内六角圆柱头螺钉(GB/T 70.1) • 弹簧垫圈(GB/T 93) • 深沟球轴承(简化模型)
作业 4:Claude Code 实战(推荐)
使用 Claude Code 完成以下任务:
1. 让 Claude 帮你创建一个 M8x30 内六角螺栓 2. 让 Claude 为螺栓添加材料属性和重量计算 3. 让 Claude 生成一个包含螺栓、螺母、垫圈的装配体
总结
Day 2 我们深入学习了参数化设计的核心理念和实操技能:
1. 参数化思维:用参数和约束表达设计意图,而非直接操作几何体 2. 标准件规范:学会查表、建立参数字典、处理公差配合 3. 螺栓实战:用 CadQuery 创建了支持四种规格的参数化六角头螺栓 4. 齿轮实战:实现了渐开线直齿轮的参数化建模,理解了齿轮啮合原理 5. 标准件库:建立了规范的文件夹结构和 JSON 配置管理体系 6. 批量处理:实现了自动化批量生成,大幅提升建模效率
关键收获
参数化设计 + AI = 工程设计效率的质变。你不再需要为每个规格重复建模,只需定义好参数关系,让 AI 和代码帮你完成剩下的工作。
Day 3 预告
在 Day 3 中,我们将学习装配体与约束,内容包括:
• 多零件装配的原理和方法 • 装配约束(同轴、面贴合、距离等) • 运动仿真基础 • 用 AI 辅助完成复杂装配体设计
参考资源
版权声明 | 本系列课程为"Text-to-CAD:AI驱动的CAD建模革命"训练营的一部分,仅供学习交流使用。
夜雨聆风