x
This commit is contained in:
@@ -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:
|
||||
@@ -447,57 +454,36 @@ class AluminumFoamMoldGenerator:
|
||||
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"]
|
||||
primary_direction = [0, 0, 1] # Z 轴方向
|
||||
|
||||
# 沿主方向创建分型面
|
||||
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)
|
||||
# 分型面位于包围盒 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:
|
||||
"""计算产品重量"""
|
||||
|
||||
@@ -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:
|
||||
return (bbox_dims[0] * bbox_dims[1]) / 100
|
||||
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
|
||||
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,12 +71,25 @@ class CalculationService:
|
||||
cavity_count: int,
|
||||
runner_ratio: float = 0.20,
|
||||
injection_pressure: float = 700,
|
||||
is_foam: bool = False,
|
||||
) -> int:
|
||||
"""
|
||||
计算所需夹紧力(吨)
|
||||
|
||||
塑料模具: 锁模力 = 投影面积 × 型腔数 × (1+流道比) × 注塑压力 / 1000
|
||||
泡沫模具: 锁模力 = 投影面积(cm²) × 0.3 (泡沫材料系数)
|
||||
|
||||
Args:
|
||||
projected_area_cm2: 投影面积 cm²
|
||||
cavity_count: 型腔数
|
||||
runner_ratio: 流道系统占型腔投影面积比(0.15-0.25)
|
||||
injection_pressure: 注塑压力 kg/cm²
|
||||
is_foam: 是否泡沫材料
|
||||
"""
|
||||
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))
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user