From f8f034552a51e0dd246ee0e1393b552f62fb44c1 Mon Sep 17 00:00:00 2001 From: chenjw28 <792430652@qq.com> Date: Tue, 21 Apr 2026 14:41:58 +0800 Subject: [PATCH] x --- src/core/aluminum_foam_mold.py | 98 +++++++++++++---------------- src/services/calculation_service.py | 62 +++++++++++++++--- 2 files changed, 97 insertions(+), 63 deletions(-) diff --git a/src/core/aluminum_foam_mold.py b/src/core/aluminum_foam_mold.py index d1eef74..042d599 100644 --- a/src/core/aluminum_foam_mold.py +++ b/src/core/aluminum_foam_mold.py @@ -247,9 +247,12 @@ class AluminumFoamMoldGenerator: "manufacturing_info": { "estimated_mold_size": self._calculate_mold_size(analysis), "estimated_clamping_force": self._calculate_clamping_force(analysis), + "clamping_force_formula": "投影面积(cm²) × 0.3 (泡沫材料系数)", "recommended_material": material_info.get("description", "Aluminum Foam Mold"), "molding_temperature": material_info.get("molding_temp", 380), - "expansion_ratio": material_info.get("expansion_ratio", 2.5) + "expansion_ratio": material_info.get("expansion_ratio", 2.5), + "parting_direction": "Z", + "parting_description": "Z轴上下开模,分型面位于包围盒Z中心", }, "quality_checks": { "undercut_regions": cavity_data.get("undercut_regions", []), @@ -436,7 +439,11 @@ class AluminumFoamMoldGenerator: def _detect_parting_surfaces(self, shape: Any, analysis: Dict) -> Dict[str, Any]: """ - 检测分型面(支持多分型面) + 检测分型面(泡沫模具专用) + + 规则: + 1. 优先选择 Z 轴方向分型(上下开模) + 2. 分型面位置选在产品的最大轮廓处,即包围盒的 Z 方向中心 """ # 1. 尝试 AI 模型 if self.ai_parting_detector is not None: @@ -446,58 +453,37 @@ class AluminumFoamMoldGenerator: return self._create_parting_surface_from_ai(ai_result, analysis) except Exception as e: logger.warning(f"AI 分型面检测失败: {e}") - - # 2. 法向量分析确定主方向 - normal_stats = analysis.get("normal_statistics", {}) - primary_direction = normal_stats.get("primary_direction", [0, 0, 1]) - - # 3. 创建主分型面 + + # 2. 泡沫模具强制 Z 轴方向分型(上下开模) bbox = analysis["bounding_box"] center = bbox["center"] - - # 沿主方向创建分型面 - dir_obj = gp_Dir(primary_direction[0], primary_direction[1], primary_direction[2]) - parting_plane = gp_Pln(gp_Pnt(center[0], center[1], center[2]), dir_obj) - + primary_direction = [0, 0, 1] # Z 轴方向 + + # 分型面位于包围盒 Z 方向中心(最大轮廓处) + parting_z = center[2] + parting_plane = gp_Pln(gp_Pnt(center[0], center[1], parting_z), gp_Dir(0, 0, 1)) + try: parting_surface = BRepBuilderAPI_MakeFace(parting_plane).Face() except Exception: # 回退到默认平面 - parting_plane = gp_Pln(gp_Pnt(0, 0, center[2]), gp_Dir(0, 0, 1)) + parting_plane = gp_Pln(gp_Pnt(0, 0, parting_z), gp_Dir(0, 0, 1)) parting_surface = BRepBuilderAPI_MakeFace(parting_plane).Face() - - # 4. 计算分型线 + + logger.info(f"泡沫模具 Z 轴分型面: Z={parting_z:.2f} mm (包围盒中心)") + + # 3. 计算分型线 parting_line = self._calculate_parting_line(shape, parting_surface) - - # 5. 检测是否需要多分型面(基于产品复杂度) - additional_surfaces = [] - - # 检查产品高度方向的比例 - dims = bbox["dimensions"] - max_dim = max(dims) - min_dim = min(dims) - - # 如果产品非常扁平,可能需要水平分型面 - if max_dim / min_dim > 5: - # 尝试添加垂直分型面 - vertical_plane = gp_Pln(gp_Pnt(center[0], center[1], center[2]), gp_Dir(1, 0, 0)) - try: - vertical_surface = BRepBuilderAPI_MakeFace(vertical_plane).Face() - additional_surfaces.append({ - "surface": vertical_surface, - "direction": [1, 0, 0], - "reason": "产品扁平,需要垂直分型" - }) - except Exception: - pass - + return { "primary_surface": parting_surface, "primary_line": parting_line, "primary_direction": primary_direction, - "confidence": normal_stats.get("confidence", 0.5), - "additional_surfaces": additional_surfaces, - "surface_count": 1 + len(additional_surfaces) + "confidence": 0.95, # Z 轴分型置信度高 + "additional_surfaces": [], + "surface_count": 1, + "parting_direction": "Z", + "parting_position_z": parting_z, } def _detect_undercut_regions(self, shape: Any, parting_surface: Any) -> List[Dict]: @@ -904,17 +890,23 @@ class AluminumFoamMoldGenerator: } def _calculate_clamping_force(self, analysis: Dict) -> str: - """估算锁模力""" - volume_cm3 = analysis.get("volume", 0) / 1000 - - if volume_cm3 < 10: - return "30-50 吨" - elif volume_cm3 < 50: - return "50-100 吨" - elif volume_cm3 < 200: - return "100-200 吨" - else: - return "200+ 吨" + """ + 估算锁模力(泡沫模具专用) + + 公式: 锁模力(吨) = 投影面积(cm²) × 0.3 (泡沫材料系数) + 投影面积 = 长度 × 宽度 (Z轴开模) + """ + bbox = analysis.get("bounding_box", {}) + dims = bbox.get("dimensions", [0, 0, 0]) + + # 投影面积 = 长度 × 宽度 (mm² → cm²) + projected_area_cm2 = (dims[0] * dims[1]) / 100 if len(dims) >= 2 else 0 + + # 锁模力(吨) = 投影面积(cm²) × 0.3 + clamping_force_ton = int(projected_area_cm2 * 0.3) + clamping_force_ton = max(30, clamping_force_ton) + + return f"{clamping_force_ton} 吨 (投影面积 {projected_area_cm2:.1f} cm² × 0.3)" def _calculate_product_weight(self, analysis: Dict) -> str: """计算产品重量""" diff --git a/src/services/calculation_service.py b/src/services/calculation_service.py index d26af0f..dbe5914 100644 --- a/src/services/calculation_service.py +++ b/src/services/calculation_service.py @@ -18,11 +18,27 @@ class CalculationService: return volume_cm3 * density @staticmethod - def calculate_projected_area(bbox_dims: List[float]) -> float: - """计算投影面积(cm²),取 X、Y 方向""" - if len(bbox_dims) >= 2: + def calculate_projected_area(bbox_dims: List[float], parting_direction: str = "Z") -> float: + """ + 计算投影面积(cm²) + + Args: + bbox_dims: [长度, 宽度, 高度] (mm) + parting_direction: 开模方向,"Z" 表示上下开模(投影到XY平面), + "Y" 表示前后开模(投影到XZ平面), + "X" 表示左右开模(投影到YZ平面) + """ + if len(bbox_dims) < 3: + return 0.0 + if parting_direction == "Z": + # Z轴开模 → 投影面积 = 长度 × 宽度 return (bbox_dims[0] * bbox_dims[1]) / 100 - return 0.0 + elif parting_direction == "Y": + return (bbox_dims[0] * bbox_dims[2]) / 100 + elif parting_direction == "X": + return (bbox_dims[1] * bbox_dims[2]) / 100 + # 默认 Z 轴 + return (bbox_dims[0] * bbox_dims[1]) / 100 @staticmethod def calculate_cavity_count(product_weight_g: float, projected_area_cm2: float) -> int: @@ -55,14 +71,27 @@ class CalculationService: cavity_count: int, runner_ratio: float = 0.20, injection_pressure: float = 700, + is_foam: bool = False, ) -> int: """ 计算所需夹紧力(吨) - runner_ratio: 流道系统占型腔投影面积比(0.15-0.25) - injection_pressure: 注塑压力 kg/cm² + + 塑料模具: 锁模力 = 投影面积 × 型腔数 × (1+流道比) × 注塑压力 / 1000 + 泡沫模具: 锁模力 = 投影面积(cm²) × 0.3 (泡沫材料系数) + + Args: + projected_area_cm2: 投影面积 cm² + cavity_count: 型腔数 + runner_ratio: 流道系统占型腔投影面积比(0.15-0.25) + injection_pressure: 注塑压力 kg/cm² + is_foam: 是否泡沫材料 """ - total_projected_area = projected_area_cm2 * cavity_count * (1 + runner_ratio) - clamping_force_ton = int(total_projected_area * injection_pressure / 1000) + if is_foam: + # 泡沫模具: 锁模力(吨) = 投影面积(cm²) × 0.3 + clamping_force_ton = int(projected_area_cm2 * 0.3) + else: + total_projected_area = projected_area_cm2 * cavity_count * (1 + runner_ratio) + clamping_force_ton = int(total_projected_area * injection_pressure / 1000) return max(50, min(clamping_force_ton, 3000)) @staticmethod @@ -165,13 +194,19 @@ class CalculationService: material_density = material["density"] shrinkage_rate = material["shrinkage"] + is_foam = material.get("is_foam", False) + + # 泡沫模具优先 Z 轴开模(上下开模) + parting_direction = "Z" # 各项计算 volume_cm3 = volume_mm3 / 1000 product_weight_g = cls.calculate_product_weight(volume_mm3, material_density) - projected_area_cm2 = cls.calculate_projected_area(bbox_dims) + projected_area_cm2 = cls.calculate_projected_area(bbox_dims, parting_direction) cavity_count = cls.calculate_cavity_count(product_weight_g, projected_area_cm2) - clamping_force_ton = cls.calculate_clamping_force(projected_area_cm2, cavity_count) + clamping_force_ton = cls.calculate_clamping_force( + projected_area_cm2, cavity_count, is_foam=is_foam + ) wall = cls.calculate_wall_thickness(volume_mm3, surface_area_mm2) complexity_score = cls.calculate_complexity(wall["avg_thickness_mm"]) mold_size = cls.calculate_mold_size(bbox_dims, cavity_count) @@ -187,6 +222,8 @@ class CalculationService: "shrinkage_rate": shrinkage_rate, "draft_angle": 2.0, "selected_material": material["name"], + "is_foam": is_foam, + "parting_direction": parting_direction, }, "product_analysis": { "volume": volume_mm3, @@ -197,6 +234,10 @@ class CalculationService: "recommended_material": material["name"], "material_density": f"{material_density} g/cm³", "estimated_clamping_force": f"{clamping_force_ton} 吨", + "clamping_force_formula": ( + "投影面积(cm²) × 0.3" if is_foam + else "投影面积 × 型腔数 × (1+流道比) × 注塑压力 / 1000" + ), "estimated_mold_size": { "length": int(mold_size["length"]), "width": int(mold_size["width"]), @@ -208,6 +249,7 @@ class CalculationService: "parting_line_length": f"{parting_line_length:.2f} mm", "estimated_cycle_time": f"{cycle_time} 秒", "injection_pressure": f"{injection_pressure} kg/cm²", + "parting_direction": parting_direction, }, "mold_cavities": { "cavity_count": cavity_count,