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

Cadquery平移箱体后切割报错:Null TopoDS_Shape对象问题求助

CadQuery多边形切割箱体问题解决方案

问题描述

我有一个从GDS文件单元中导入的多边形顶点列表(命名为polygons),尝试用这些形状对箱体执行全贯穿切割,遇到两个问题:

  1. 仅当挤出深度设置为-(box_h + 0.0001)时切割才能完全贯穿箱体,若设为-box_h则无法切穿;
  2. 将箱体平移至多边形中心后,执行cut操作抛出「ValueError: Null TopoDS_Shape object」错误,虽然可视化装配体显示正常,但无法完成切割。

未平移箱体时的代码

cellCen = (0.5841240000000001, 0.8565)   # 导入多边形单元的中心坐标
(box_w, box_l, box_h) = (1.968248, 2.513, 0.038)  # 箱体尺寸
slab = cq.Workplane("front").box(box_w, box_l, box_h)
pols = [slab.faces(">Z").workplane().polyline(polygons[i]).close().extrude(-(box_h + 0.0001), combine = False) for i in range(len(polygons))]
p0 = pols[0]
for i in range(len(pols)):
    # p0 成为要从箱体中切除的实体组
    p0 = p0.union(pols[i], glue = True)   

slab.cut(p0)

平移箱体后的代码

slab = cq.Workplane("front").box(box_w, box_l, box_h).translate((cellCen[0]/2 , cellCen[1]/2 , 0))   # 将箱体平移至多边形单元的XY中心
pols = [slab.faces(">Z").workplane().polyline(polygons[i]).close().extrude(-(box_h + 0.0001), combine = False) for i in range(len(polygons))]
p0 = pols[0]
for i in range(len(pols)):
    # p0 成为要从箱体中切除的实体组
    p0 = p0.union(pols[i], glue = True)   

slab.cut(p0)

可视化装配体代码

assy = cq.Assembly()

assy = addToAssembly(assy, slab, "sub", color = cq.Color("Gold"))
assy = addToAssembly(assy, (p0), "trench", color = cq.Color("black"))

display(assy)

问题1分析与解决

原因

CadQuery依赖的OpenCASCADE引擎对共面边界的布尔运算存在精度阈值:当挤出深度恰好等于箱体高度box_h时,挤出体的底面与箱体底面完全共面,引擎会判定两个实体没有形成有效的"贯穿交集",导致切割操作不生效。

解决方法

使用cutThruAll()方法替代指定深度的extrude(),该方法会自动识别目标实体的范围并完全贯穿,彻底避免精度问题:

# 替换原挤出语句
pols = [slab.faces(">Z").workplane().polyline(polygons[i]).close().cutThruAll(combine=False) for i in range(len(polygons))]

若坚持使用extrude,可采用相对箱体尺寸的安全偏移(如-box_h * 1.001),但cutThruAll()是最简洁可靠的方案。


问题2分析与解决

原因

  1. 平移量计算错误:默认box()创建的箱体中心在原点,要与多边形单元中心cellCen对齐,应平移至cellCen而非其半值,原代码的平移量导致箱体与多边形位置不匹配;
  2. 工作平面坐标偏移:基于平移后的箱体表面创建工作平面,会使多边形顶点的坐标系跟随箱体偏移,导致部分多边形落在箱体外部,union后生成无效的空形状,触发Null TopoDS_Shape错误。

解决方法

  1. 修正平移逻辑:将箱体中心准确移至多边形单元中心:
slab = cq.Workplane("front").box(box_w, box_l, box_h).translate((cellCen[0], cellCen[1], 0))
  1. 使用全局坐标系创建多边形:直接基于全局XY平面构建多边形,确保坐标与导入的polygons匹配:
pols = [cq.Workplane("XY").polyline(polygons[i]).close().cutThruAll(combine=False) for i in range(len(polygons))]
  1. 过滤无效实体:在union前检查每个挤出体的有效性,跳过空形状:
p0 = None
for pol in pols:
    if not pol.val().Shape().IsNull():
        if p0 is None:
            p0 = pol
        else:
            p0 = p0.union(pol, glue=True)
# 仅当p0有效时执行切割
if p0 is not None:
    slab = slab.cut(p0)

内容的提问来源于stack exchange,提问作者Shrinivas Ganti

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 20:23:09