diff --git a/src/core/aluminum_foam_mold.py b/src/core/aluminum_foam_mold.py index 042d599..4306f0b 100644 --- a/src/core/aluminum_foam_mold.py +++ b/src/core/aluminum_foam_mold.py @@ -702,44 +702,79 @@ class AluminumFoamMoldGenerator: return shape def _split_cavity_core(self, shape: Any, parting_surface: Any) -> Tuple[Any, Any]: - """分离型腔和型芯(优化版)""" + """ + 按分型面将模具分为 A 板(定模/型腔侧)和 B 板(动模/型芯侧) + + 流程: + 1. 创建模具块(包围产品的长方体) + 2. 用分型面水平切出上半块和下半块 + 3. 从上半块减去产品 → A 板(含型腔负形) + 4. 从下半块减去产品 → B 板(含型芯负形) + """ try: - # 获取边界框 + # 获取产品边界框 bbox = Bnd_Box() brepbndlib_Add(shape, bbox) xmin, ymin, zmin, xmax, ymax, zmax = bbox.Get() - - # 计算模具块尺寸 - margin = 25 # 铝泡沫模具需要更大余量 + + # 获取分型面 Z 位置(包围盒 Z 中心) + parting_z = (zmin + zmax) / 2 + + # 模具块尺寸(比产品大一圈余量) + margin = 25 mold_xmin = xmin - margin mold_ymin = ymin - margin mold_zmin = zmin - margin mold_xmax = xmax + margin mold_ymax = ymax + margin mold_zmax = zmax + margin - - # 创建模具块 + + # Step 1: 创建整块模具 mold_block = BRepPrimAPI_MakeBox( gp_Pnt(mold_xmin, mold_ymin, mold_zmin), gp_Pnt(mold_xmax, mold_ymax, mold_zmax) ).Shape() - - # 型腔 = 模具块 - 产品 - cavity_operation = BRepAlgoAPI_Cut(mold_block, shape) - if cavity_operation.IsDone(): - cavity = cavity_operation.Shape() - logger.info("型腔生成成功") + + # Step 2: 用分型面切出上下半块 + # 创建一个足够大的水平切割面(分型面 Z 位置) + cutting_plane = gp_Pln(gp_Pnt(0, 0, parting_z), gp_Dir(0, 0, 1)) + cutting_face = BRepBuilderAPI_MakeFace(cutting_plane).Face() + + # 创建上半空间和下半空间的实体 + # 上半块: 从 parting_z 到 mold_zmax + upper_block = BRepPrimAPI_MakeBox( + gp_Pnt(mold_xmin, mold_ymin, parting_z), + gp_Pnt(mold_xmax, mold_ymax, mold_zmax) + ).Shape() + + # 下半块: 从 mold_zmin 到 parting_z + lower_block = BRepPrimAPI_MakeBox( + gp_Pnt(mold_xmin, mold_ymin, mold_zmin), + gp_Pnt(mold_xmax, mold_ymax, parting_z) + ).Shape() + + # Step 3: 从上半块减去产品 → A 板(定模) + a_plate_op = BRepAlgoAPI_Cut(upper_block, shape) + if a_plate_op.IsDone(): + a_plate = a_plate_op.Shape() + logger.info(f"A板(定模)生成成功: Z={parting_z:.1f} ~ {mold_zmax:.1f}") else: - logger.warning("型腔布尔运算失败") - cavity = mold_block - - # 型芯 = 产品形状 - core = shape - - return cavity, core - + logger.warning("A板布尔减法失败,使用上半块") + a_plate = upper_block + + # Step 4: 从下半块减去产品 → B 板(动模) + b_plate_op = BRepAlgoAPI_Cut(lower_block, shape) + if b_plate_op.IsDone(): + b_plate = b_plate_op.Shape() + logger.info(f"B板(动模)生成成功: Z={mold_zmin:.1f} ~ {parting_z:.1f}") + else: + logger.warning("B板布尔减法失败,使用下半块") + b_plate = lower_block + + return a_plate, b_plate + except Exception as e: - logger.error(f"型腔分离失败: {e}") + logger.error(f"分模失败: {e}") return shape, shape def _generate_mold_block(self, cavity: Any, analysis: Dict) -> Any: diff --git a/src/core/mold_generator.py b/src/core/mold_generator.py index 7e4a539..54dbc0d 100644 --- a/src/core/mold_generator.py +++ b/src/core/mold_generator.py @@ -315,10 +315,14 @@ class MoldCavityGenerator: return shape def _split_cavity_core(self, shape: Any, parting_surface: Any) -> Tuple[Any, Any]: - """分离型腔和型芯 - - 型腔(Cavity): 模具中形成产品外表面的部分,是产品形状的负形 - 型芯(Core): 模具中形成产品内表面的部分,是产品形状的正形 + """ + 按分型面将模具分为 A 板(定模/型腔侧)和 B 板(动模/型芯侧) + + 流程: + 1. 创建模具块(包围产品的长方体) + 2. 用分型面 Z 位置切出上半块和下半块 + 3. 从上半块减去产品 → A 板(含型腔负形) + 4. 从下半块减去产品 → B 板(含型芯负形) """ try: from OCC.Core.BRepPrimAPI import BRepPrimAPI_MakeBox @@ -333,6 +337,9 @@ class MoldCavityGenerator: brepbndlib.Add(shape, bbox) xmin, ymin, zmin, xmax, ymax, zmax = bbox.Get() + # 获取分型面 Z 位置(包围盒 Z 中心) + parting_z = (zmin + zmax) / 2 + # 计算模具块尺寸(比产品大一定余量) margin = 20 # mm mold_xmin = xmin - margin @@ -341,30 +348,41 @@ class MoldCavityGenerator: mold_xmax = xmax + margin mold_ymax = ymax + margin mold_zmax = zmax + margin - - # 创建模具块 - mold_block = BRepPrimAPI_MakeBox( - gp_Pnt(mold_xmin, mold_ymin, mold_zmin), + + # 上半块: 从 parting_z 到 mold_zmax + upper_block = BRepPrimAPI_MakeBox( + gp_Pnt(mold_xmin, mold_ymin, parting_z), gp_Pnt(mold_xmax, mold_ymax, mold_zmax) ).Shape() - - # 型腔 = 模具块 - 产品(布尔减法) - cavity_operation = BRepAlgoAPI_Cut(mold_block, shape) - if cavity_operation.IsDone(): - cavity = cavity_operation.Shape() - logger.info("型腔生成成功(模具块减去产品)") + + # 下半块: 从 mold_zmin 到 parting_z + lower_block = BRepPrimAPI_MakeBox( + gp_Pnt(mold_xmin, mold_ymin, mold_zmin), + gp_Pnt(mold_xmax, mold_ymax, parting_z) + ).Shape() + + # A 板(定模)= 上半块 - 产品 + a_plate_op = BRepAlgoAPI_Cut(upper_block, shape) + if a_plate_op.IsDone(): + a_plate = a_plate_op.Shape() + logger.info(f"A板(定模)生成成功: Z={parting_z:.1f} ~ {mold_zmax:.1f}") else: - logger.warning("型腔布尔运算失败,使用原始形状") - cavity = mold_block - - # 型芯 = 产品形状本身(收缩补偿后) - core = shape - logger.info("型芯 = 产品形状") - - return cavity, core + logger.warning("A板布尔减法失败,使用上半块") + a_plate = upper_block + + # B 板(动模)= 下半块 - 产品 + b_plate_op = BRepAlgoAPI_Cut(lower_block, shape) + if b_plate_op.IsDone(): + b_plate = b_plate_op.Shape() + logger.info(f"B板(动模)生成成功: Z={mold_zmin:.1f} ~ {parting_z:.1f}") + else: + logger.warning("B板布尔减法失败,使用下半块") + b_plate = lower_block + + return a_plate, b_plate except Exception as e: - logger.error(f"型腔分离失败: {e}") + logger.error(f"分模失败: {e}") return shape, shape def _extract_shape_geometry(self, shape: Any, shape_type: str) -> Dict[str, Any]: diff --git a/src/utils/html_generator.py b/src/utils/html_generator.py index 58eed89..d53b773 100644 --- a/src/utils/html_generator.py +++ b/src/utils/html_generator.py @@ -80,7 +80,7 @@ class HTMLGenerator: 制造要求
- 型腔材料: + 模仁材料: {manufacturing_info.get("mold_material", "N/A")}
@@ -176,7 +176,7 @@ class HTMLGenerator: - + @@ -278,7 +278,7 @@ class HTMLGenerator: scene.add(productMesh); }} - // 创建型腔(上半模 - 蓝色) + // 创建A板/定模(蓝色,分型面以上) // 尝试从后端数据获取实际几何,否则使用简化Box if (cavityData && cavityData.mold_cavities && cavityData.mold_cavities.cavity && cavityData.mold_cavities.cavity.vertices) {{ const cavityVerts = cavityData.mold_cavities.cavity.vertices; @@ -324,7 +324,7 @@ class HTMLGenerator: createSimpleCavity(width, height, depth); }} - // 创建型芯(下半模 - 橙色) + // 创建B板/动模(橙色,分型面以下) if (cavityData && cavityData.mold_cavities && cavityData.mold_cavities.core && cavityData.mold_cavities.core.vertices) {{ const coreVerts = cavityData.mold_cavities.core.vertices; const coreFaces = cavityData.mold_cavities.core.faces; @@ -389,9 +389,11 @@ class HTMLGenerator: }} }} - // 创建简化型腔(备用) + // 创建简化型腔/A板(定模,分型面以上)— 备用 function createSimpleCavity(width, height, depth) {{ - const cavityGeometry = new THREE.BoxGeometry(width * 1.2, height * 0.4, depth * 1.2); + // A板:分型面(Z中心)以上的上半模 + const halfHeight = height / 2; + const cavityGeometry = new THREE.BoxGeometry(width * 1.2, depth * 1.2, halfHeight + 10); const cavityMaterial = new THREE.MeshPhongMaterial({{ color: 0x2196F3, transparent: true, @@ -400,7 +402,8 @@ class HTMLGenerator: }}); cavityMesh = new THREE.Mesh(cavityGeometry, cavityMaterial); - cavityMesh.position.set(0, height * 0.7, 0); + // Z轴开模:A板放在分型面以上 + cavityMesh.position.set(0, 0, halfHeight / 2 + 5); scene.add(cavityMesh); const cavityWireframe = new THREE.WireframeGeometry(cavityGeometry); @@ -412,9 +415,11 @@ class HTMLGenerator: cavityMesh.add(cavityLine); }} - // 创建简化型芯(备用) + // 创建简化型芯/B板(动模,分型面以下)— 备用 function createSimpleCore(width, height, depth) {{ - const coreGeometry = new THREE.BoxGeometry(width * 1.2, height * 0.4, depth * 1.2); + // B板:分型面(Z中心)以下的下半模 + const halfHeight = height / 2; + const coreGeometry = new THREE.BoxGeometry(width * 1.2, depth * 1.2, halfHeight + 10); const coreMaterial = new THREE.MeshPhongMaterial({{ color: 0xFF9800, transparent: true, @@ -423,7 +428,8 @@ class HTMLGenerator: }}); coreMesh = new THREE.Mesh(coreGeometry, coreMaterial); - coreMesh.position.set(0, -height * 0.7, 0); + // Z轴开模:B板放在分型面以下 + coreMesh.position.set(0, 0, -halfHeight / 2 - 5); scene.add(coreMesh); const coreWireframe = new THREE.WireframeGeometry(coreGeometry);