修改分模逻辑为注塑模

This commit is contained in:
2026-05-06 17:20:54 +08:00
parent 1b54f2f7a8
commit 2fb3b0271c
13 changed files with 492 additions and 76 deletions
+78 -62
View File
@@ -226,13 +226,14 @@ class BaseMoldGenerator:
def _split_cavity_core(self, shape: Any, parting_surface: Any, margin: int = 20) -> Tuple[Any, Any]:
"""
分离型腔和型芯
分离型腔和型芯 — 完全嵌入 + 突出贴合方式
正确流程:
1. 创建模具块(产品边界框 + 余量)
2. 用分型面将模具块切分为 A板(上模)和 B板(下模)
3. A板减去产品 → 型腔(凹模)
4. B板减去产品 → 型芯(凸模)
流程:
1. 创建完整模具块(产品包围盒 + 全方向余量)
2. 型腔(凹模)= 模具块 - 产品 → 产品完全嵌入型腔块中
3. 型芯(凸模)= 产品形状突出体 → 从芯块面突出贴合
不再使用分型面中间切开产品的方式。
"""
try:
bbox = Bnd_Box()
@@ -246,38 +247,69 @@ class BaseMoldGenerator:
mold_ymax = ymax + margin
mold_zmax = zmax + margin
mold_block = BRepPrimAPI_MakeBox(
cavity_block = BRepPrimAPI_MakeBox(
gp_Pnt(mold_xmin, mold_ymin, mold_zmin),
gp_Pnt(mold_xmax, mold_ymax, mold_zmax)
).Shape()
parting_plane = self._get_parting_plane(parting_surface, shape)
if parting_plane is None:
logger.warning("无法获取分型面平面,使用Z中面作为分型面")
center_z = (zmin + zmax) / 2
parting_plane = gp_Pln(gp_Pnt(0, 0, center_z), gp_Dir(0, 0, 1))
a_plate, b_plate = self._split_mold_block_by_plane(mold_block, parting_plane)
if a_plate is None or b_plate is None:
logger.warning("A/B板分离失败,回退到简化方法")
return self._split_cavity_core_fallback(shape, mold_block)
cavity = self._subtract_product_from_plate(a_plate, shape, "A板")
core = self._subtract_product_from_plate(b_plate, shape, "B板")
cavity = self._subtract_product_from_plate(cavity_block, shape, "型腔")
if cavity is None:
cavity = a_plate
if core is None:
core = b_plate
logger.warning("型腔布尔减运算失败,使用原始模具块")
cavity = cavity_block
logger.info("型腔/型芯分离完成(基于分型面A/B板切分)")
core = self._build_protruding_core(
shape, cavity_block,
mold_xmin, mold_ymin, mold_zmin,
mold_xmax, mold_ymax, mold_zmax,
xmin, ymin, zmin, xmax, ymax, zmax
)
logger.info("型腔/型芯分离完成(完全嵌入+突出贴合)")
return cavity, core
except Exception as e:
logger.error(f"型腔分离失败: {e}")
return self._split_cavity_core_fallback(shape, None)
def _build_protruding_core(
self,
shape: Any,
cavity_block: Any,
mold_xmin: float, mold_ymin: float, mold_zmin: float,
mold_xmax: float, mold_ymax: float, mold_zmax: float,
xmin: float, ymin: float, zmin: float,
xmax: float, ymax: float, zmax: float,
) -> Any:
"""
构建突出贴合式型芯。
型芯 = 模具块 ∩ 产品形状 → 产品突出体。
从视觉上:型芯面突出产品形状,与型腔的凹入形状完美贴合。
"""
try:
common_op = BRepAlgoAPI_Common(cavity_block, shape)
if common_op.IsDone():
core = common_op.Shape()
logger.info("型芯突出体构建成功(布尔交)")
return core
except Exception as e:
logger.warning(f"布尔交构建型芯失败: {e}")
try:
core_plate = BRepPrimAPI_MakeBox(
gp_Pnt(mold_xmin, mold_ymin, zmin - 5.0),
gp_Pnt(mold_xmax, mold_ymax, zmin)
).Shape()
cut_op = BRepAlgoAPI_Cut(cavity_block, shape)
if cut_op.IsDone():
logger.info("型芯突出体构建成功(布尔减回退)")
return cut_op.Shape()
except Exception:
pass
logger.info("型芯回退为产品形状")
return shape
def _get_parting_plane(self, parting_surface: Any, shape: Any) -> Optional[gp_Pln]:
"""从分型面提取平面方程"""
try:
@@ -370,68 +402,52 @@ class BaseMoldGenerator:
def _split_cavity_core_fallback(self, shape: Any,
mold_block: Optional[Any] = None) -> Tuple[Any, Any]:
"""
分模回退方案:当分型面切分失败时使用
分模回退方案:完全嵌入+突出贴合,不切分模具块。
使用Z中面将模具块简单切分为上下两半
1. 创建完整模具块 → 型腔 = 模具块 - 产品(产品完全嵌入)
2. 型芯 = 产品形状突出体(突出贴合)
"""
logger.warning("使用分模回退方案(Z中面切分)")
logger.warning("使用分模回退方案(完全嵌入+突出贴合)")
try:
bbox = Bnd_Box()
brepbndlib.Add(shape, bbox)
xmin, ymin, zmin, xmax, ymax, zmax = bbox.Get()
margin = 20
if mold_block is None:
margin = 20
mold_block = BRepPrimAPI_MakeBox(
gp_Pnt(xmin - margin, ymin - margin, zmin - margin),
gp_Pnt(xmax + margin, ymax + margin, zmax + margin)
).Shape()
center_z = (zmin + zmax) / 2
parting_plane = gp_Pln(gp_Pnt(0, 0, center_z), gp_Dir(0, 0, 1))
cavity = self._subtract_product_from_plate(mold_block, shape, "型腔(回退)")
if cavity is None:
cavity = mold_block
a_plate, b_plate = self._split_mold_block_by_plane(mold_block, parting_plane)
core = self._build_protruding_core(
shape, mold_block,
xmin - margin, ymin - margin, zmin - margin,
xmax + margin, ymax + margin, zmax + margin,
xmin, ymin, zmin, xmax, ymax, zmax
)
if a_plate is not None and b_plate is not None:
cavity = self._subtract_product_from_plate(a_plate, shape, "A板(回退)")
core = self._subtract_product_from_plate(b_plate, shape, "B板(回退)")
return cavity or a_plate, core or b_plate
logger.warning("回退方案也失败,使用最简A/B板切分(避免返回产品本体)")
center_z = (zmin + zmax) / 2
margin = 20
a_plate = BRepPrimAPI_MakeBox(
gp_Pnt(xmin - margin, ymin - margin, center_z),
gp_Pnt(xmax + margin, ymax + margin, zmax + margin)
).Shape()
b_plate = BRepPrimAPI_MakeBox(
gp_Pnt(xmin - margin, ymin - margin, zmin - margin),
gp_Pnt(xmax + margin, ymax + margin, center_z)
).Shape()
cavity = self._subtract_product_from_plate(a_plate, shape, "A板(最简)")
core = self._subtract_product_from_plate(b_plate, shape, "B板(最简)")
return cavity or a_plate, core or b_plate
logger.info("回退方案型腔/型芯分离完成")
return cavity or mold_block, core
except Exception as e:
logger.error(f"分模回退方案失败: {e}")
# 最后兜底也返回模具半板,而不是产品本体,避免预览出现“三份产品”
try:
bbox = Bnd_Box()
brepbndlib.Add(shape, bbox)
xmin, ymin, zmin, xmax, ymax, zmax = bbox.Get()
center_z = (zmin + zmax) / 2
margin = 20
a_plate = BRepPrimAPI_MakeBox(
gp_Pnt(xmin - margin, ymin - margin, center_z),
cavity_block = BRepPrimAPI_MakeBox(
gp_Pnt(xmin - margin, ymin - margin, zmin - margin),
gp_Pnt(xmax + margin, ymax + margin, zmax + margin)
).Shape()
b_plate = BRepPrimAPI_MakeBox(
gp_Pnt(xmin - margin, ymin - margin, zmin - margin),
gp_Pnt(xmax + margin, ymax + margin, center_z)
).Shape()
return a_plate, b_plate
cavity = self._subtract_product_from_plate(cavity_block, shape, "型腔(兜底)")
return cavity or cavity_block, shape
except Exception:
return shape, shape