Merge branch 'main' of http://szcjw:10001/cjw/geMoldInsight
This commit is contained in:
@@ -230,9 +230,12 @@ class AluminumFoamMoldGenerator(BaseMoldGenerator):
|
||||
"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", []),
|
||||
@@ -301,8 +304,13 @@ class AluminumFoamMoldGenerator(BaseMoldGenerator):
|
||||
|
||||
def _detect_parting_surfaces(self, shape: Any, analysis: Dict) -> Dict[str, Any]:
|
||||
"""
|
||||
检测分型面(支持多分型面)
|
||||
检测分型面(泡沫模具专用)
|
||||
|
||||
规则:
|
||||
1. 优先选择 Z 轴方向分型(上下开模)
|
||||
2. 分型面位置选在产品的最大轮廓处,即包围盒的 Z 方向中心
|
||||
"""
|
||||
<<<<<<< HEAD
|
||||
primary_parting = self._detect_primary_parting(shape, analysis)
|
||||
parting_surface = primary_parting["surface"]
|
||||
parting_line = self.optimize_parting_line(primary_parting["line"])
|
||||
@@ -328,15 +336,54 @@ class AluminumFoamMoldGenerator(BaseMoldGenerator):
|
||||
})
|
||||
except Exception:
|
||||
pass
|
||||
=======
|
||||
# 1. 尝试 AI 模型
|
||||
if self.ai_parting_detector is not None:
|
||||
try:
|
||||
ai_result = self.ai_parting_detector.detect(shape, analysis)
|
||||
if ai_result:
|
||||
return self._create_parting_surface_from_ai(ai_result, analysis)
|
||||
except Exception as e:
|
||||
logger.warning(f"AI 分型面检测失败: {e}")
|
||||
|
||||
# 2. 泡沫模具强制 Z 轴方向分型(上下开模)
|
||||
bbox = analysis["bounding_box"]
|
||||
center = bbox["center"]
|
||||
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, parting_z), gp_Dir(0, 0, 1))
|
||||
parting_surface = BRepBuilderAPI_MakeFace(parting_plane).Face()
|
||||
|
||||
logger.info(f"泡沫模具 Z 轴分型面: Z={parting_z:.2f} mm (包围盒中心)")
|
||||
|
||||
# 3. 计算分型线
|
||||
parting_line = self._calculate_parting_line(shape, parting_surface)
|
||||
>>>>>>> 77c4885a4020b609f4964184661f42e936814c4f
|
||||
|
||||
return {
|
||||
"primary_surface": parting_surface,
|
||||
"primary_line": parting_line,
|
||||
"primary_direction": primary_direction,
|
||||
<<<<<<< HEAD
|
||||
"confidence": primary_parting["confidence"],
|
||||
"method": primary_parting["method"],
|
||||
"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,
|
||||
>>>>>>> 77c4885a4020b609f4964184661f42e936814c4f
|
||||
}
|
||||
|
||||
def _build_undercut_regions(self, undercut_analysis: Dict[str, Any]) -> List[Dict[str, Any]]:
|
||||
@@ -416,7 +463,120 @@ class AluminumFoamMoldGenerator(BaseMoldGenerator):
|
||||
|
||||
except Exception:
|
||||
return 50.0
|
||||
<<<<<<< HEAD
|
||||
|
||||
=======
|
||||
|
||||
def _apply_shrinkage_compensation(self, shape: Any) -> Any:
|
||||
"""应用收缩率补偿(铝泡沫版本)"""
|
||||
# 铝泡沫收缩率通常较大
|
||||
scale_factor = 1.0 + self.shrinkage_rate
|
||||
|
||||
trsf = gp_Trsf()
|
||||
trsf.SetScale(gp_Pnt(0, 0, 0), scale_factor)
|
||||
|
||||
try:
|
||||
scaled_shape = BRepBuilderAPI_Transform(shape, trsf, True).Shape()
|
||||
logger.info(f"收缩率补偿应用: {self.shrinkage_rate*100:.2f}%")
|
||||
return scaled_shape
|
||||
except Exception as e:
|
||||
logger.error(f"收缩补偿失败: {e}")
|
||||
return shape
|
||||
|
||||
def _apply_draft_angles(self, shape: Any, parting_surface: Any) -> Any:
|
||||
"""应用拔模角(改进版)"""
|
||||
# 获取分型面法向量作为拔模方向
|
||||
try:
|
||||
surface = BRepAdaptor_Surface(parting_surface)
|
||||
draft_direction = surface.Plane().Position().Direction()
|
||||
|
||||
logger.info(f"应用拔模角: {self.draft_angle}°, 方向: ({draft_direction.X():.3f}, {draft_direction.Y():.3f}, {draft_direction.Z():.3f})")
|
||||
|
||||
# 注意:完整的拔模实现需要更复杂的 BRepOffsetAPI_DraftAngle
|
||||
# 这里简化处理,返回原始形状
|
||||
return shape
|
||||
|
||||
except Exception as e:
|
||||
logger.warning(f"拔模角处理失败: {e}")
|
||||
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()
|
||||
|
||||
# 获取分型面 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()
|
||||
|
||||
# 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("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}")
|
||||
return shape, shape
|
||||
|
||||
>>>>>>> 77c4885a4020b609f4964184661f42e936814c4f
|
||||
def _generate_mold_block(self, cavity: Any, analysis: Dict) -> Any:
|
||||
"""生成完整的模具块(包含A/B板结构)"""
|
||||
try:
|
||||
@@ -496,6 +656,7 @@ class AluminumFoamMoldGenerator(BaseMoldGenerator):
|
||||
}
|
||||
|
||||
def _calculate_clamping_force(self, analysis: Dict) -> str:
|
||||
<<<<<<< HEAD
|
||||
"""估算锁模力"""
|
||||
volume_cm3 = analysis.get("volume", 0) / 1000
|
||||
|
||||
@@ -508,6 +669,32 @@ class AluminumFoamMoldGenerator(BaseMoldGenerator):
|
||||
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:
|
||||
"""计算产品重量"""
|
||||
volume_cm3 = analysis.get("volume", 0) / 1000
|
||||
weight_g = volume_cm3 * self.material_density
|
||||
return f"{weight_g:.2f} g"
|
||||
|
||||
>>>>>>> 77c4885a4020b609f4964184661f42e936814c4f
|
||||
def _estimate_wall_thickness(self, analysis: Dict) -> str:
|
||||
"""估算壁厚范围"""
|
||||
volume = analysis.get("volume", 0)
|
||||
|
||||
@@ -237,6 +237,7 @@ class MoldCavityGenerator(BaseMoldGenerator):
|
||||
logger.info(f"转换得到 {len(regions)} 个兼容倒扣区域")
|
||||
return regions
|
||||
|
||||
<<<<<<< HEAD
|
||||
def _analyze_face_normals(self, shape: Any) -> gp_Dir:
|
||||
"""
|
||||
分析产品表面的法向量分布,找出最优分型方向
|
||||
@@ -248,6 +249,87 @@ class MoldCavityGenerator(BaseMoldGenerator):
|
||||
"""
|
||||
face_normals = []
|
||||
explorer = TopExp_Explorer(shape, TopAbs_FACE)
|
||||
=======
|
||||
return scaled_shape
|
||||
|
||||
def _apply_draft_angles(self, shape: Any, parting_surface: Any) -> Any:
|
||||
"""添加拔模角(简化实现)"""
|
||||
# 实际实现需要复杂的拔模面处理
|
||||
# 这里返回原始形状(假设已在CAD中处理)
|
||||
logger.warning("拔模角处理为简化实现,建议在设计阶段处理")
|
||||
return shape
|
||||
|
||||
def _split_cavity_core(self, shape: Any, parting_surface: Any) -> Tuple[Any, Any]:
|
||||
"""
|
||||
按分型面将模具分为 A 板(定模/型腔侧)和 B 板(动模/型芯侧)
|
||||
|
||||
流程:
|
||||
1. 创建模具块(包围产品的长方体)
|
||||
2. 用分型面 Z 位置切出上半块和下半块
|
||||
3. 从上半块减去产品 → A 板(含型腔负形)
|
||||
4. 从下半块减去产品 → B 板(含型芯负形)
|
||||
"""
|
||||
try:
|
||||
from OCC.Core.BRepPrimAPI import BRepPrimAPI_MakeBox
|
||||
from OCC.Core.BRepAlgoAPI import BRepAlgoAPI_Cut
|
||||
from OCC.Core.TopExp import TopExp_Explorer
|
||||
from OCC.Core.TopAbs import TopAbs_SOLID
|
||||
|
||||
# 获取产品边界框
|
||||
from OCC.Core.Bnd import Bnd_Box
|
||||
from OCC.Core.BRepBndLib import brepbndlib
|
||||
bbox = Bnd_Box()
|
||||
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
|
||||
mold_ymin = ymin - margin
|
||||
mold_zmin = zmin - margin
|
||||
mold_xmax = xmax + margin
|
||||
mold_ymax = ymax + margin
|
||||
mold_zmax = zmax + margin
|
||||
|
||||
# 上半块: 从 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()
|
||||
|
||||
# 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("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}")
|
||||
return shape, shape
|
||||
>>>>>>> 77c4885a4020b609f4964184661f42e936814c4f
|
||||
|
||||
while explorer.More():
|
||||
face = TopoDS_Face(explorer.Current())
|
||||
|
||||
Reference in New Issue
Block a user