This commit is contained in:
2026-04-23 00:49:22 +08:00
parent 882756412e
commit cccb0920ae
5 changed files with 314 additions and 312 deletions
+51 -39
View File
@@ -12,6 +12,7 @@ from OCC.Core.BRepBndLib import brepbndlib_Add
from models.schemas import create_mold_cavity_data, create_mold_key_info
from utils.logger import get_logger
from core.base_mold_generator import BaseMoldGenerator
from core.side_action_designer import SideActionDesigner
logger = get_logger(__name__)
@@ -36,6 +37,7 @@ class MoldCavityGenerator(BaseMoldGenerator):
self.parting_line_tolerance = 0.1
self.max_draft_angle = 5.0
self.side_action_designer = SideActionDesigner()
def set_material(self, material: str):
"""设置产品材料"""
@@ -62,8 +64,19 @@ class MoldCavityGenerator(BaseMoldGenerator):
try:
analysis = self._analyze_product_geometry(product_shape)
parting_surface, parting_line = self._detect_parting_surface(
product_shape, analysis
parting_result = self._detect_primary_parting(product_shape, analysis)
parting_surface = parting_result["surface"]
parting_line = self.optimize_parting_line(parting_result["line"])
parting_direction = parting_result["direction"]
side_action_result = self.side_action_designer.analyze_and_design(
shape=product_shape,
parting_direction=parting_direction,
mold_size=self._calculate_mold_size(analysis),
parting_surface=parting_surface,
)
undercut_regions = self._build_undercut_regions(
side_action_result.get("undercut_analysis", {})
)
scaled_shape = self._apply_shrinkage_compensation(product_shape)
@@ -79,7 +92,9 @@ class MoldCavityGenerator(BaseMoldGenerator):
"core": core,
"parting_surface": parting_surface,
"parting_line": parting_line,
"analysis": analysis
"analysis": analysis,
"undercut_regions": undercut_regions,
"side_actions": side_action_result,
}
except Exception as e:
@@ -124,6 +139,10 @@ class MoldCavityGenerator(BaseMoldGenerator):
"core": core_geometry
},
"parting_surface": parting_geometry,
"quality_checks": {
"undercut_regions": cavity_data.get("undercut_regions", []),
"side_actions": cavity_data.get("side_actions", {}),
},
"manufacturing_info": {
"estimated_mold_size": self._calculate_mold_size(analysis),
"estimated_clamping_force": self._calculate_clamping_force(analysis),
@@ -165,6 +184,8 @@ class MoldCavityGenerator(BaseMoldGenerator):
"recommended_injection_pressure": "80-120 MPa"
},
"quality_considerations": {
"undercut_count": len(cavity_data.get("undercut_regions", [])),
"side_action_summary": cavity_data.get("side_actions", {}).get("summary", {}),
"potential_weld_lines": self._identify_weld_line_risk(analysis),
"sink_mark_areas": self._identify_sink_mark_risk(analysis),
"warpage_risk": self._assess_warpage_risk(analysis)
@@ -184,26 +205,13 @@ class MoldCavityGenerator(BaseMoldGenerator):
2. 基于法向量分析的几何方法
3. 简化方法(基于边界框)
"""
if self.ai_parting_detector is not None:
try:
logger.info("使用 AI 模型检测分型面")
ai_result = self.ai_parting_detector.detect(shape, analysis)
if ai_result:
return self._create_parting_surface_from_ai(ai_result, analysis, shape)
except Exception as e:
logger.warning(f"AI 分型面检测失败,回退到几何方法:{e}")
try:
logger.info("使用法向量分析检测分型面")
optimal_direction = self._analyze_face_normals(shape)
parting_plane = self._create_optimal_parting_plane(
shape, analysis, optimal_direction
parting_result = self._detect_primary_parting(shape, analysis)
logger.info(
f"使用 {parting_result['method']} 方法检测分型面,"
f"置信度={parting_result['confidence']:.3f}"
)
parting_surface = BRepBuilderAPI_MakeFace(parting_plane).Face()
parting_line = self._calculate_parting_line(shape, parting_surface)
return parting_surface, parting_line
return parting_result["surface"], self.optimize_parting_line(parting_result["line"])
except Exception as e:
logger.warning(f"法向量分析失败,使用简化方法:{e}")
@@ -211,6 +219,24 @@ class MoldCavityGenerator(BaseMoldGenerator):
logger.info("使用简化方法检测分型面")
return self._simple_parting_surface(shape, analysis)
def _build_undercut_regions(self, undercut_analysis: Dict[str, Any]) -> List[Dict[str, Any]]:
"""将侧向机构分析结果转换为兼容旧结构的倒扣区域列表。"""
undercut_faces = undercut_analysis.get("undercut_faces", [])
regions = []
for face in undercut_faces:
regions.append({
"type": "negative_draft",
"location": face.get("center", [0, 0, 0]),
"severity": face.get("severity", "medium"),
"area": face.get("area", 0),
"is_outer": face.get("is_outer", False),
"face_index": face.get("face_index"),
})
logger.info(f"转换得到 {len(regions)} 个兼容倒扣区域")
return regions
def _analyze_face_normals(self, shape: Any) -> gp_Dir:
"""
分析产品表面的法向量分布,找出最优分型方向
@@ -335,27 +361,13 @@ class MoldCavityGenerator(BaseMoldGenerator):
def _extract_parting_surface_geometry(self, surface: Any) -> Dict[str, Any]:
"""提取分型面几何数据"""
try:
adaptor = BRepAdaptor_Surface(surface)
u_min, u_max = adaptor.FirstUParameter(), adaptor.LastUParameter()
v_min, v_max = adaptor.FirstVParameter(), adaptor.LastVParameter()
bounds = {
"u_range": [float(u_min), float(u_max)],
"v_range": [float(v_min), float(v_max)]
}
except Exception as e:
logger.warning(f"分型面边界提取失败,使用默认值: {e}")
bounds = {
"u_range": [-200, 200],
"v_range": [-200, 200]
}
metadata = self._extract_plane_metadata(surface)
return {
"type": "plane",
"normal": [0, 0, 1],
"origin": [0, 0, 0],
"bounds": bounds
"normal": metadata["normal"],
"origin": metadata["origin"],
"bounds": metadata["bounds"],
}
def _calculate_mold_size(self, analysis: Dict) -> Dict[str, float]: