导出step文件合并为整体,方便后续修改

This commit is contained in:
2026-05-27 14:57:03 +08:00
parent 26613676f8
commit 9882d3becc
11 changed files with 129 additions and 111 deletions
+5 -4
View File
@@ -6,6 +6,7 @@ AI 分模辅助模型接口示例
""" """
from typing import Dict, Any, Optional from typing import Dict, Any, Optional
import numpy as np import numpy as np
from OCC.Core.TopoDS import TopoDS_Shape, TopoDS_Face
class AIPartingSurfaceDetector: class AIPartingSurfaceDetector:
@@ -40,7 +41,7 @@ class AIPartingSurfaceDetector:
# self.model = torch.load(model_path) # self.model = torch.load(model_path)
print(f"AI 模型加载:{model_path}") print(f"AI 模型加载:{model_path}")
def detect(self, product_shape: Any, analysis: Dict) -> Optional[Dict]: def detect(self, product_shape: TopoDS_Shape, analysis: Dict) -> Optional[Dict]:
""" """
检测最优分型面 检测最优分型面
@@ -76,7 +77,7 @@ class AIPartingSurfaceDetector:
"undercut_regions": [] # 倒扣区域 "undercut_regions": [] # 倒扣区域
} }
def _preprocess_shape(self, shape: Any, analysis: Dict) -> Any: def _preprocess_shape(self, shape: TopoDS_Shape, analysis: Dict) -> TopoDS_Shape:
""" """
预处理产品形状为 AI 模型输入 预处理产品形状为 AI 模型输入
@@ -110,7 +111,7 @@ class AIDraftAnalyzer:
"""加载训练好的 AI 模型""" """加载训练好的 AI 模型"""
print(f"AI 拔模分析模型加载:{model_path}") print(f"AI 拔模分析模型加载:{model_path}")
def analyze(self, product_shape: Any, parting_surface: Any, def analyze(self, product_shape: TopoDS_Shape, parting_surface: TopoDS_Face,
base_draft_angle: float) -> Optional[Dict]: base_draft_angle: float) -> Optional[Dict]:
""" """
分析拔模需求 分析拔模需求
@@ -156,7 +157,7 @@ class AICavityLayoutOptimizer:
if model_path: if model_path:
self._load_model(model_path) self._load_model(model_path)
def optimize(self, product_shape: Any, cavity_count: int, def optimize(self, product_shape: TopoDS_Shape, cavity_count: int,
mold_base_size: Dict) -> Optional[Dict]: mold_base_size: Dict) -> Optional[Dict]:
""" """
优化型腔布局 优化型腔布局
+6 -5
View File
@@ -22,6 +22,7 @@ GNN 模型:
from typing import Dict, List, Any, Optional, Tuple from typing import Dict, List, Any, Optional, Tuple
import numpy as np import numpy as np
from OCC.Core.TopoDS import TopoDS_Shape
from utils.logger import get_logger from utils.logger import get_logger
logger = get_logger(__name__) logger = get_logger(__name__)
@@ -47,7 +48,7 @@ except ImportError:
class ShapeGraphBuilder: class ShapeGraphBuilder:
"""将 OCC 形状转换为图表示""" """将 OCC 形状转换为图表示"""
def build_graph(self, shape: Any) -> Optional[Dict]: def build_graph(self, shape: TopoDS_Shape) -> Optional[Dict]:
""" """
从 OCC 形状构建图数据 从 OCC 形状构建图数据
@@ -383,7 +384,7 @@ class AIPartingSurfaceDetectorV2:
logger.error(f"GNN 模型加载失败: {e}") logger.error(f"GNN 模型加载失败: {e}")
self.model = None self.model = None
def detect(self, product_shape: Any, analysis: Dict) -> Optional[Dict]: def detect(self, product_shape: TopoDS_Shape, analysis: Dict) -> Optional[Dict]:
""" """
检测最优分型面 检测最优分型面
@@ -407,7 +408,7 @@ class AIPartingSurfaceDetectorV2:
return self._detect_with_geometry(product_shape, analysis) return self._detect_with_geometry(product_shape, analysis)
def _detect_with_gnn(self, shape: Any, analysis: Dict) -> Optional[Dict]: def _detect_with_gnn(self, shape: TopoDS_Shape, analysis: Dict) -> Optional[Dict]:
"""使用 GNN 模型检测分型面""" """使用 GNN 模型检测分型面"""
if not _TORCH_GEOMETRIC_AVAILABLE: if not _TORCH_GEOMETRIC_AVAILABLE:
return None return None
@@ -457,7 +458,7 @@ class AIPartingSurfaceDetectorV2:
logger.warning(f"GNN 检测失败,回退到几何方法: {e}") logger.warning(f"GNN 检测失败,回退到几何方法: {e}")
return None return None
def _detect_with_geometry(self, shape: Any, analysis: Dict) -> Dict: def _detect_with_geometry(self, shape: TopoDS_Shape, analysis: Dict) -> Dict:
"""几何方法回退:基于法向量统计的分型面检测""" """几何方法回退:基于法向量统计的分型面检测"""
try: try:
graph_data = self.graph_builder.build_graph(shape) graph_data = self.graph_builder.build_graph(shape)
@@ -504,7 +505,7 @@ class AIPartingSurfaceDetectorV2:
"method": "fallback", "method": "fallback",
} }
def collect_training_sample(self, shape: Any, analysis: Dict, def collect_training_sample(self, shape: TopoDS_Shape, analysis: Dict,
ground_truth_normal: List[float], ground_truth_normal: List[float],
ground_truth_origin: List[float]) -> Optional[Dict]: ground_truth_origin: List[float]) -> Optional[Dict]:
""" """
+9 -9
View File
@@ -16,7 +16,7 @@ import numpy as np
from OCC.Core.BRepBuilderAPI import BRepBuilderAPI_MakeFace from OCC.Core.BRepBuilderAPI import BRepBuilderAPI_MakeFace
from OCC.Core.BRepPrimAPI import BRepPrimAPI_MakeBox from OCC.Core.BRepPrimAPI import BRepPrimAPI_MakeBox
from OCC.Core.gp import gp_Pln, gp_Dir, gp_Pnt from OCC.Core.gp import gp_Pln, gp_Dir, gp_Pnt
from OCC.Core.TopoDS import TopoDS_Face, topods from OCC.Core.TopoDS import TopoDS_Face, TopoDS_Shape, topods
from OCC.Core.BRepAdaptor import BRepAdaptor_Surface from OCC.Core.BRepAdaptor import BRepAdaptor_Surface
from OCC.Core.TopExp import TopExp_Explorer from OCC.Core.TopExp import TopExp_Explorer
from OCC.Core.TopAbs import TopAbs_FACE from OCC.Core.TopAbs import TopAbs_FACE
@@ -128,7 +128,7 @@ class AluminumFoamMoldGenerator(BaseMoldGenerator):
else: else:
logger.warning(f"未知材料 {material}") logger.warning(f"未知材料 {material}")
def generate_mold_cavities(self, product_shape: Any) -> Dict[str, Any]: def generate_mold_cavities(self, product_shape: TopoDS_Shape) -> Dict[str, Any]:
""" """
从产品的3D模型生成型腔和型芯 从产品的3D模型生成型腔和型芯
@@ -292,13 +292,13 @@ class AluminumFoamMoldGenerator(BaseMoldGenerator):
# ==================== 核心算法实现 ==================== # ==================== 核心算法实现 ====================
def _analyze_product_geometry(self, shape: Any) -> Dict[str, Any]: def _analyze_product_geometry(self, shape: TopoDS_Shape) -> Dict[str, Any]:
"""分析产品几何属性(扩展基类版本,增加法向量统计)""" """分析产品几何属性(扩展基类版本,增加法向量统计)"""
result = super()._analyze_product_geometry(shape) result = super()._analyze_product_geometry(shape)
result["normal_statistics"] = self._analyze_parting_direction(shape) result["normal_statistics"] = self._analyze_parting_direction(shape)
return result return result
def _analyze_parting_direction(self, shape: Any) -> Dict[str, float]: def _analyze_parting_direction(self, shape: TopoDS_Shape) -> Dict[str, float]:
"""分析产品法向量分布,按面积加权统计各轴方向强度""" """分析产品法向量分布,按面积加权统计各轴方向强度"""
stats = {"X": 0.0, "Y": 0.0, "Z": 0.0} stats = {"X": 0.0, "Y": 0.0, "Z": 0.0}
explorer = TopExp_Explorer(shape, TopAbs_FACE) explorer = TopExp_Explorer(shape, TopAbs_FACE)
@@ -328,11 +328,11 @@ class AluminumFoamMoldGenerator(BaseMoldGenerator):
for axis, value in stats.items() for axis, value in stats.items()
} }
def _split_cavity_core(self, shape: Any, parting_surface: Any) -> Tuple[Any, Any]: def _split_cavity_core(self, shape: TopoDS_Shape, parting_surface: TopoDS_Face) -> Tuple[TopoDS_Shape, TopoDS_Shape]:
"""分离型腔和型芯(铝泡沫使用更大余量)""" """分离型腔和型芯(铝泡沫使用更大余量)"""
return super()._split_cavity_core(shape, parting_surface, margin=25) return super()._split_cavity_core(shape, parting_surface, margin=25)
def _detect_parting_surfaces(self, shape: Any, analysis: Dict) -> Dict[str, Any]: def _detect_parting_surfaces(self, shape: TopoDS_Shape, analysis: Dict) -> Dict[str, Any]:
""" """
检测分型面(泡沫模具专用) 检测分型面(泡沫模具专用)
@@ -470,7 +470,7 @@ class AluminumFoamMoldGenerator(BaseMoldGenerator):
except Exception: except Exception:
return 50.0 return 50.0
def _generate_mold_block(self, cavity: Any, analysis: Dict) -> Any: def _generate_mold_block(self, cavity: TopoDS_Shape, analysis: Dict) -> TopoDS_Shape:
"""生成完整的模具块(包含A/B板结构)""" """生成完整的模具块(包含A/B板结构)"""
try: try:
bbox = analysis["bounding_box"] bbox = analysis["bounding_box"]
@@ -493,7 +493,7 @@ class AluminumFoamMoldGenerator(BaseMoldGenerator):
logger.error(f"模具块生成失败: {e}") logger.error(f"模具块生成失败: {e}")
return cavity return cavity
def _extract_parting_surface_geometry(self, surface: Any) -> Dict[str, Any]: def _extract_parting_surface_geometry(self, surface: TopoDS_Face) -> Dict[str, Any]:
"""提取分型面几何数据""" """提取分型面几何数据"""
metadata = self._extract_plane_metadata(surface) metadata = self._extract_plane_metadata(surface)
return { return {
@@ -504,7 +504,7 @@ class AluminumFoamMoldGenerator(BaseMoldGenerator):
} }
def _create_parting_surface_from_ai(self, ai_result: Dict, analysis: Dict, def _create_parting_surface_from_ai(self, ai_result: Dict, analysis: Dict,
shape: Any = None) -> Dict: shape: Optional[TopoDS_Shape] = None) -> Dict:
"""从 AI 结果创建分型面""" """从 AI 结果创建分型面"""
origin = ai_result.get("origin", [0, 0, 0]) origin = ai_result.get("origin", [0, 0, 0])
normal = ai_result.get("normal", [0, 0, 1]) normal = ai_result.get("normal", [0, 0, 1])
+32 -32
View File
@@ -1,4 +1,4 @@
from typing import Dict, List, Any, Tuple, Optional from typing import Dict, List, Any, Tuple, Optional, TYPE_CHECKING
import math import math
import numpy as np import numpy as np
from OCC.Core.BRepOffsetAPI import BRepOffsetAPI_DraftAngle from OCC.Core.BRepOffsetAPI import BRepOffsetAPI_DraftAngle
@@ -6,7 +6,7 @@ from OCC.Core.BRepAlgoAPI import BRepAlgoAPI_Cut, BRepAlgoAPI_Section, BRepAlgoA
from OCC.Core.BRepBuilderAPI import BRepBuilderAPI_MakeFace, BRepBuilderAPI_Transform from OCC.Core.BRepBuilderAPI import BRepBuilderAPI_MakeFace, BRepBuilderAPI_Transform
from OCC.Core.BRepPrimAPI import BRepPrimAPI_MakeBox, BRepPrimAPI_MakeHalfSpace from OCC.Core.BRepPrimAPI import BRepPrimAPI_MakeBox, BRepPrimAPI_MakeHalfSpace
from OCC.Core.gp import gp_Pln, gp_Dir, gp_Pnt, gp_Trsf, gp_Ax2 from OCC.Core.gp import gp_Pln, gp_Dir, gp_Pnt, gp_Trsf, gp_Ax2
from OCC.Core.TopoDS import TopoDS_Face, TopoDS_Compound, topods from OCC.Core.TopoDS import TopoDS_Shape, TopoDS_Face, TopoDS_Compound, topods
from OCC.Core.BRep import BRep_Tool, BRep_Builder from OCC.Core.BRep import BRep_Tool, BRep_Builder
from OCC.Core.BRepMesh import BRepMesh_IncrementalMesh from OCC.Core.BRepMesh import BRepMesh_IncrementalMesh
from OCC.Core.GProp import GProp_GProps from OCC.Core.GProp import GProp_GProps
@@ -41,7 +41,7 @@ class BaseMoldGenerator:
self.ai_draft_analyzer = draft_analyzer self.ai_draft_analyzer = draft_analyzer
logger.info("AI 模型接口已设置") logger.info("AI 模型接口已设置")
def _apply_shrinkage_compensation(self, shape: Any) -> Any: def _apply_shrinkage_compensation(self, shape: TopoDS_Shape) -> TopoDS_Shape:
scale_factor = 1.0 + self.shrinkage_rate scale_factor = 1.0 + self.shrinkage_rate
trsf = gp_Trsf() trsf = gp_Trsf()
trsf.SetScale(gp_Pnt(0, 0, 0), scale_factor) trsf.SetScale(gp_Pnt(0, 0, 0), scale_factor)
@@ -53,7 +53,7 @@ class BaseMoldGenerator:
logger.warning(f"收缩率补偿失败: {e}") logger.warning(f"收缩率补偿失败: {e}")
return shape return shape
def _apply_draft_angles(self, shape: Any, parting_surface: Any) -> Any: def _apply_draft_angles(self, shape: TopoDS_Shape, parting_surface: TopoDS_Face) -> TopoDS_Shape:
try: try:
draft_direction = self._get_draft_direction(parting_surface) draft_direction = self._get_draft_direction(parting_surface)
if draft_direction is None: if draft_direction is None:
@@ -76,7 +76,7 @@ class BaseMoldGenerator:
logger.warning(f"拔模角处理失败,返回原始形状: {e}") logger.warning(f"拔模角处理失败,返回原始形状: {e}")
return shape return shape
def _get_draft_direction(self, parting_surface: Any) -> Optional[gp_Dir]: def _get_draft_direction(self, parting_surface: TopoDS_Face) -> Optional[gp_Dir]:
try: try:
surface = BRepAdaptor_Surface(parting_surface) surface = BRepAdaptor_Surface(parting_surface)
if surface.GetType() == 0: if surface.GetType() == 0:
@@ -85,7 +85,7 @@ class BaseMoldGenerator:
except Exception: except Exception:
return gp_Dir(0, 0, 1) return gp_Dir(0, 0, 1)
def _find_draftable_faces(self, shape: Any, draft_direction: gp_Dir) -> List[Any]: def _find_draftable_faces(self, shape: TopoDS_Shape, draft_direction: gp_Dir) -> List[TopoDS_Face]:
draftable = [] draftable = []
explorer = TopExp_Explorer(shape, TopAbs_FACE) explorer = TopExp_Explorer(shape, TopAbs_FACE)
@@ -103,7 +103,7 @@ class BaseMoldGenerator:
return draftable return draftable
def _get_face_normal(self, face: Any) -> Optional[gp_Dir]: def _get_face_normal(self, face: TopoDS_Face) -> Optional[gp_Dir]:
try: try:
surface = BRepAdaptor_Surface(face) surface = BRepAdaptor_Surface(face)
u = (surface.FirstUParameter() + surface.LastUParameter()) / 2 u = (surface.FirstUParameter() + surface.LastUParameter()) / 2
@@ -122,8 +122,8 @@ class BaseMoldGenerator:
except Exception: except Exception:
return None return None
def _execute_draft(self, shape: Any, faces: List[Any], def _execute_draft(self, shape: TopoDS_Shape, faces: List[TopoDS_Face],
draft_direction: gp_Dir, draft_angle_rad: float) -> Any: draft_direction: gp_Dir, draft_angle_rad: float) -> TopoDS_Shape:
try: try:
draft = BRepOffsetAPI_DraftAngle(shape) draft = BRepOffsetAPI_DraftAngle(shape)
@@ -156,8 +156,8 @@ class BaseMoldGenerator:
logger.warning(f"拔模执行失败: {e}") logger.warning(f"拔模执行失败: {e}")
return shape return shape
def _draft_faces_sequentially(self, shape: Any, faces: List[Any], def _draft_faces_sequentially(self, shape: TopoDS_Shape, faces: List[TopoDS_Face],
draft_direction: gp_Dir, draft_angle_rad: float) -> Any: draft_direction: gp_Dir, draft_angle_rad: float) -> TopoDS_Shape:
current_shape = shape current_shape = shape
success_count = 0 success_count = 0
@@ -190,7 +190,7 @@ class BaseMoldGenerator:
return current_shape return current_shape
def _analyze_product_geometry(self, shape: Any) -> Dict[str, Any]: def _analyze_product_geometry(self, shape: TopoDS_Shape) -> Dict[str, Any]:
try: try:
props = GProp_GProps() props = GProp_GProps()
brepgprop.VolumeProperties(shape, props) brepgprop.VolumeProperties(shape, props)
@@ -224,7 +224,7 @@ class BaseMoldGenerator:
logger.error(f"产品几何分析失败: {e}") logger.error(f"产品几何分析失败: {e}")
raise raise
def _split_cavity_core(self, shape: Any, parting_surface: Any, margin: int = 20) -> Tuple[Any, Any]: def _split_cavity_core(self, shape: TopoDS_Shape, parting_surface: TopoDS_Face, margin: int = 20) -> Tuple[TopoDS_Shape, TopoDS_Shape]:
""" """
分离型腔和型芯 — 完全嵌入 + 突出贴合方式。 分离型腔和型芯 — 完全嵌入 + 突出贴合方式。
@@ -274,7 +274,7 @@ class BaseMoldGenerator:
return self._split_cavity_core_fallback(shape, None) return self._split_cavity_core_fallback(shape, None)
@staticmethod @staticmethod
def _extract_parting_normal(parting_surface: Any) -> List[float]: def _extract_parting_normal(parting_surface: TopoDS_Face) -> List[float]:
"""从分型面提取法向量""" """从分型面提取法向量"""
try: try:
surface = BRepAdaptor_Surface(parting_surface) surface = BRepAdaptor_Surface(parting_surface)
@@ -288,14 +288,14 @@ class BaseMoldGenerator:
def _build_core_with_base( def _build_core_with_base(
self, self,
shape: Any, shape: TopoDS_Shape,
mold_block: Any, mold_block: TopoDS_Shape,
parting_plane: gp_Pln, parting_plane: gp_Pln,
mold_xmin: float, mold_ymin: float, mold_zmin: float, mold_xmin: float, mold_ymin: float, mold_zmin: float,
mold_xmax: float, mold_ymax: float, mold_zmax: float, mold_xmax: float, mold_ymax: float, mold_zmax: float,
xmin: float, ymin: float, zmin: float, xmin: float, ymin: float, zmin: float,
xmax: float, ymax: float, zmax: float, xmax: float, ymax: float, zmax: float,
) -> Any: ) -> TopoDS_Shape:
""" """
构建带底座的型芯。 构建带底座的型芯。
@@ -353,7 +353,7 @@ class BaseMoldGenerator:
return self._build_core_compound(base_plate, shape) return self._build_core_compound(base_plate, shape)
@staticmethod @staticmethod
def _build_core_compound(base_plate: Any, shape: Any) -> Any: def _build_core_compound(base_plate: TopoDS_Shape, shape: TopoDS_Shape) -> TopoDS_Shape:
""" """
兜底方案:构建 TopoDS_Compound 包含底座平板 + 产品。 兜底方案:构建 TopoDS_Compound 包含底座平板 + 产品。
即使布尔融合失败,底座也绝不会丢失。 即使布尔融合失败,底座也绝不会丢失。
@@ -366,7 +366,7 @@ class BaseMoldGenerator:
logger.info("型芯 Compound 兜底构建 (底座+产品)") logger.info("型芯 Compound 兜底构建 (底座+产品)")
return compound return compound
def _get_parting_plane(self, parting_surface: Any, shape: Any) -> Optional[gp_Pln]: def _get_parting_plane(self, parting_surface: TopoDS_Face, shape: TopoDS_Shape) -> Optional[gp_Pln]:
"""从分型面提取平面方程""" """从分型面提取平面方程"""
try: try:
surface = BRepAdaptor_Surface(parting_surface) surface = BRepAdaptor_Surface(parting_surface)
@@ -383,8 +383,8 @@ class BaseMoldGenerator:
logger.warning(f"分型面平面提取失败: {e}") logger.warning(f"分型面平面提取失败: {e}")
return None return None
def _split_mold_block_by_plane(self, mold_block: Any, def _split_mold_block_by_plane(self, mold_block: TopoDS_Shape,
parting_plane: gp_Pln) -> Tuple[Any, Any]: parting_plane: gp_Pln) -> Tuple[TopoDS_Shape, TopoDS_Shape]:
""" """
用分型面将模具块切分为A板(上模)和B板(下模) 用分型面将模具块切分为A板(上模)和B板(下模)
@@ -439,8 +439,8 @@ class BaseMoldGenerator:
logger.error(f"A/B板分离失败: {e}") logger.error(f"A/B板分离失败: {e}")
return None, None return None, None
def _subtract_product_from_plate(self, plate: Any, product: Any, def _subtract_product_from_plate(self, plate: TopoDS_Shape, product: TopoDS_Shape,
plate_name: str) -> Any: plate_name: str) -> TopoDS_Shape:
"""从模板中减去产品形状,生成型腔或型芯""" """从模板中减去产品形状,生成型腔或型芯"""
try: try:
cut_op = BRepAlgoAPI_Cut(plate, product) cut_op = BRepAlgoAPI_Cut(plate, product)
@@ -455,8 +455,8 @@ class BaseMoldGenerator:
logger.warning(f"{plate_name}减产品失败: {e}") logger.warning(f"{plate_name}减产品失败: {e}")
return plate return plate
def _split_cavity_core_fallback(self, shape: Any, def _split_cavity_core_fallback(self, shape: TopoDS_Shape,
mold_block: Optional[Any] = None) -> Tuple[Any, Any]: mold_block: Optional[TopoDS_Shape] = None) -> Tuple[TopoDS_Shape, TopoDS_Shape]:
""" """
分模回退方案:完全嵌入 + 突出贴合,用 Z 中心面做分型基准。 分模回退方案:完全嵌入 + 突出贴合,用 Z 中心面做分型基准。
""" """
@@ -507,7 +507,7 @@ class BaseMoldGenerator:
except Exception: except Exception:
return shape, shape return shape, shape
def detect_insert_regions(self, shape: Any, analysis: Dict, def detect_insert_regions(self, shape: TopoDS_Shape, analysis: Dict,
depth_threshold: float = 30.0, depth_threshold: float = 30.0,
aspect_threshold: float = 3.0) -> List[Dict[str, Any]]: aspect_threshold: float = 3.0) -> List[Dict[str, Any]]:
""" """
@@ -618,7 +618,7 @@ class BaseMoldGenerator:
return inserts return inserts
def _extract_shape_geometry(self, shape: Any, shape_type: str) -> Dict[str, Any]: def _extract_shape_geometry(self, shape: TopoDS_Shape, shape_type: str) -> Dict[str, Any]:
try: try:
mesh = BRepMesh_IncrementalMesh(shape, 0.1) mesh = BRepMesh_IncrementalMesh(shape, 0.1)
mesh.Perform() mesh.Perform()
@@ -678,7 +678,7 @@ class BaseMoldGenerator:
"face_count": 0, "face_count": 0,
} }
def _extract_plane_metadata(self, surface: Any) -> Dict[str, Any]: def _extract_plane_metadata(self, surface: TopoDS_Shape) -> Dict[str, Any]:
"""从分型面提取平面元数据(法向量、原点、边界)""" """从分型面提取平面元数据(法向量、原点、边界)"""
metadata = { metadata = {
"normal": [0.0, 0.0, 1.0], "normal": [0.0, 0.0, 1.0],
@@ -743,7 +743,7 @@ class BaseMoldGenerator:
return total_length return total_length
def _calculate_parting_line(self, shape: Any, parting_surface: Any) -> List[List[float]]: def _calculate_parting_line(self, shape: TopoDS_Shape, parting_surface: TopoDS_Face) -> List[List[float]]:
try: try:
section = BRepAlgoAPI_Section(shape, parting_surface) section = BRepAlgoAPI_Section(shape, parting_surface)
section.Build() section.Build()
@@ -783,7 +783,7 @@ class BaseMoldGenerator:
logger.error(f"分型线计算失败: {e}") logger.error(f"分型线计算失败: {e}")
return self._simple_parting_line(shape) return self._simple_parting_line(shape)
def _simple_parting_line(self, shape: Any) -> List[List[float]]: def _simple_parting_line(self, shape: TopoDS_Shape) -> List[List[float]]:
try: try:
bbox = Bnd_Box() bbox = Bnd_Box()
brepbndlib.Add(shape, bbox) brepbndlib.Add(shape, bbox)
@@ -800,8 +800,8 @@ class BaseMoldGenerator:
except Exception: except Exception:
return [[-50, -50, 0], [50, -50, 0], [50, 50, 0], [-50, 50, 0], [-50, -50, 0]] return [[-50, -50, 0], [50, -50, 0], [50, 50, 0], [-50, 50, 0], [-50, -50, 0]]
def extend_parting_surface(self, parting_surface: Any, shape: Any, def extend_parting_surface(self, parting_surface: TopoDS_Face, shape: TopoDS_Shape,
extension: float = 30.0) -> Any: extension: float = 30.0) -> TopoDS_Face:
""" """
将分型面延伸到模具块边界 将分型面延伸到模具块边界
+34 -22
View File
@@ -29,6 +29,7 @@ import os
import re import re
from typing import Dict, List, Any, Optional, Tuple from typing import Dict, List, Any, Optional, Tuple
from pathlib import Path from pathlib import Path
from OCC.Core.TopoDS import TopoDS_Shape
from utils.logger import get_logger from utils.logger import get_logger
logger = get_logger(__name__) logger = get_logger(__name__)
@@ -70,7 +71,7 @@ class CADExporter:
relative = Path(os.path.basename(filepath)) relative = Path(os.path.basename(filepath))
return relative.as_posix() return relative.as_posix()
def export_step(self, shape: Any, filepath: str, def export_step(self, shape: TopoDS_Shape, filepath: str,
schema: str = "AP214") -> bool: schema: str = "AP214") -> bool:
""" """
导出 STEP 文件 导出 STEP 文件
@@ -118,7 +119,7 @@ class CADExporter:
logger.error(f"STEP 导出失败: {e}") logger.error(f"STEP 导出失败: {e}")
return False return False
def export_iges(self, shape: Any, filepath: str) -> bool: def export_iges(self, shape: TopoDS_Shape, filepath: str) -> bool:
""" """
导出 IGES 文件 导出 IGES 文件
@@ -156,7 +157,7 @@ class CADExporter:
logger.error(f"IGES 导出失败: {e}") logger.error(f"IGES 导出失败: {e}")
return False return False
def export_stl(self, shape: Any, filepath: str, def export_stl(self, shape: TopoDS_Shape, filepath: str,
ascii_mode: bool = True, ascii_mode: bool = True,
deflection: float = 0.1) -> bool: deflection: float = 0.1) -> bool:
""" """
@@ -201,7 +202,7 @@ class CADExporter:
logger.error(f"STL 导出失败: {e}") logger.error(f"STL 导出失败: {e}")
return False return False
def export_brep(self, shape: Any, filepath: str) -> bool: def export_brep(self, shape: TopoDS_Shape, filepath: str) -> bool:
""" """
导出 BRep 文件(OpenCASCADE 原生格式) 导出 BRep 文件(OpenCASCADE 原生格式)
@@ -240,18 +241,6 @@ class CADExporter:
components: List[str] = None, components: List[str] = None,
task_id: Optional[str] = None, task_id: Optional[str] = None,
scheme_id: Optional[str] = None) -> Dict[str, Any]: scheme_id: Optional[str] = None) -> Dict[str, Any]:
"""
批量导出模具设计结果
Args:
cavity_data: generate_mold_cavities() 的返回结果
base_filename: 基础文件名(不含扩展名)
formats: 导出格式列表 ["step", "iges", "stl", "brep"]
components: 导出组件列表 ["cavity", "core", "parting_surface", "all"]
Returns:
导出结果摘要
"""
if formats is None: if formats is None:
formats = ["step", "stl"] formats = ["step", "stl"]
if components is None: if components is None:
@@ -279,7 +268,8 @@ class CADExporter:
"parting_surface": ("parting_surface", "分型面"), "parting_surface": ("parting_surface", "分型面"),
} }
shapes_to_export = [] shapes_to_export: List[Tuple[str, str, TopoDS_Shape]] = []
assembly_shapes: List[Tuple[TopoDS_Shape, str]] = []
for comp in components: for comp in components:
if comp == "all": if comp == "all":
@@ -287,23 +277,45 @@ class CADExporter:
shape = cavity_data.get(data_key) shape = cavity_data.get(data_key)
if shape is not None: if shape is not None:
shapes_to_export.append((key, label, shape)) shapes_to_export.append((key, label, shape))
assembly_shapes.append((shape, label))
break break
elif comp in shape_map: elif comp in shape_map:
data_key, label = shape_map[comp] data_key, label = shape_map[comp]
shape = cavity_data.get(data_key) shape = cavity_data.get(data_key)
if shape is not None: if shape is not None:
shapes_to_export.append((comp, label, shape)) shapes_to_export.append((comp, label, shape))
assembly_shapes.append((shape, label))
else: else:
results["errors"].append(f"{label}形状不可用") results["errors"].append(f"{label}形状不可用")
# STEP: 所有组件合并为一个装配体文件
if "step" in formats and assembly_shapes:
filepath = os.path.join(export_dir, f"{base_filename}_mold.step")
success = self.export_assembly_step(assembly_shapes, filepath)
if success:
file_size = os.path.getsize(filepath)
relative_path = self.get_relative_path(filepath)
results["files"].append({
"component": "assembly",
"component_label": "模具装配体",
"format": "step",
"filepath": filepath,
"relative_path": relative_path,
"filename": os.path.basename(filepath),
"size_bytes": file_size,
"size_readable": self._format_file_size(file_size),
})
else:
results["errors"].append("装配体 STEP 导出失败")
# IGES / STL / BRep: 逐组件导出
non_assembly_formats = [f for f in formats if f != "step"]
for comp_name, label, shape in shapes_to_export: for comp_name, label, shape in shapes_to_export:
for fmt in formats: for fmt in non_assembly_formats:
filepath = os.path.join(export_dir, f"{base_filename}_{comp_name}.{fmt}") filepath = os.path.join(export_dir, f"{base_filename}_{comp_name}.{fmt}")
success = False success = False
if fmt == "step": if fmt == "iges":
success = self.export_step(shape, filepath)
elif fmt == "iges":
success = self.export_iges(shape, filepath) success = self.export_iges(shape, filepath)
elif fmt == "stl": elif fmt == "stl":
success = self.export_stl(shape, filepath) success = self.export_stl(shape, filepath)
@@ -337,7 +349,7 @@ class CADExporter:
return results return results
def export_assembly_step(self, shapes_with_names: List[Tuple[Any, str]], def export_assembly_step(self, shapes_with_names: List[Tuple[TopoDS_Shape, str]],
filepath: str, filepath: str,
schema: str = "AP214") -> bool: schema: str = "AP214") -> bool:
""" """
+11 -10
View File
@@ -1,6 +1,7 @@
from typing import Dict, List, Any, Optional from typing import Dict, List, Any, Optional
import math import math
import numpy as np import numpy as np
from OCC.Core.TopoDS import TopoDS_Shape
from models.schemas import ( from models.schemas import (
create_mold_feature, create_mold_feature,
create_design_recommendation, create_design_recommendation,
@@ -38,7 +39,7 @@ class GeometryAnalyzer:
def analyze_mold_design(self, geometry_data: Dict[str, Any], def analyze_mold_design(self, geometry_data: Dict[str, Any],
product_material: str = "ABS", product_material: str = "ABS",
mold_material: str = "Aluminum", mold_material: str = "Aluminum",
shape: Any = None shape: Optional[TopoDS_Shape] = None
) -> Dict[str, Any]: ) -> Dict[str, Any]:
"""分析模具设计 """分析模具设计
@@ -72,7 +73,7 @@ class GeometryAnalyzer:
) )
def _detect_features(self, geometry_data: Dict[str, Any], def _detect_features(self, geometry_data: Dict[str, Any],
shape: Any = None) -> List[Dict[str, Any]]: shape: Optional[TopoDS_Shape] = None) -> List[Dict[str, Any]]:
"""检测模具特征""" """检测模具特征"""
features = [] features = []
@@ -99,7 +100,7 @@ class GeometryAnalyzer:
return features return features
def _detect_wall_features(self, geometry_data: Dict[str, Any], def _detect_wall_features(self, geometry_data: Dict[str, Any],
shape: Any = None) -> List[Dict[str, Any]]: shape: Optional[TopoDS_Shape] = None) -> List[Dict[str, Any]]:
"""检测壁厚特征""" """检测壁厚特征"""
features = [] features = []
@@ -230,7 +231,7 @@ class GeometryAnalyzer:
return features return features
def _compute_precise_wall_thickness(self, shape: Any) -> Optional[Dict[str, Any]]: def _compute_precise_wall_thickness(self, shape: TopoDS_Shape) -> Optional[Dict[str, Any]]:
"""使用 BRepExtrema_DistShapeShape 精确计算壁厚""" """使用 BRepExtrema_DistShapeShape 精确计算壁厚"""
try: try:
from OCC.Core.TopExp import TopExp_Explorer from OCC.Core.TopExp import TopExp_Explorer
@@ -319,7 +320,7 @@ class GeometryAnalyzer:
return None return None
def _detect_rib_features(self, geometry_data: Dict[str, Any], def _detect_rib_features(self, geometry_data: Dict[str, Any],
shape: Any = None) -> List[Dict[str, Any]]: shape: Optional[TopoDS_Shape] = None) -> List[Dict[str, Any]]:
"""检测加强筋特征""" """检测加强筋特征"""
features = [] features = []
topology = geometry_data.get("topology", {}) topology = geometry_data.get("topology", {})
@@ -350,7 +351,7 @@ class GeometryAnalyzer:
return features return features
def _detect_boss_features(self, geometry_data: Dict[str, Any], def _detect_boss_features(self, geometry_data: Dict[str, Any],
shape: Any = None) -> List[Dict[str, Any]]: shape: Optional[TopoDS_Shape] = None) -> List[Dict[str, Any]]:
"""检测BOSS柱特征""" """检测BOSS柱特征"""
features = [] features = []
volume = geometry_data.get("volume", 0) volume = geometry_data.get("volume", 0)
@@ -382,7 +383,7 @@ class GeometryAnalyzer:
return features return features
def _analyze_draft_angles(self, geometry_data: Dict[str, Any], def _analyze_draft_angles(self, geometry_data: Dict[str, Any],
shape: Any = None) -> List[Dict[str, Any]]: shape: Optional[TopoDS_Shape] = None) -> List[Dict[str, Any]]:
"""分析拔模角度""" """分析拔模角度"""
features = [] features = []
@@ -450,7 +451,7 @@ class GeometryAnalyzer:
return features return features
def _compute_draft_angles_from_shape(self, shape: Any) -> Optional[Dict[str, Any]]: def _compute_draft_angles_from_shape(self, shape: TopoDS_Shape) -> Optional[Dict[str, Any]]:
"""基于面法向量分析计算各面的拔模角度""" """基于面法向量分析计算各面的拔模角度"""
try: try:
from OCC.Core.TopExp import TopExp_Explorer from OCC.Core.TopExp import TopExp_Explorer
@@ -516,7 +517,7 @@ class GeometryAnalyzer:
logger.warning(f"拔模角度计算失败: {e}") logger.warning(f"拔模角度计算失败: {e}")
return None return None
def _detect_curvature_features(self, shape: Any) -> List[Dict[str, Any]]: def _detect_curvature_features(self, shape: TopoDS_Shape) -> List[Dict[str, Any]]:
"""检测高曲率区域(可能导致应力集中)""" """检测高曲率区域(可能导致应力集中)"""
features = [] features = []
try: try:
@@ -604,7 +605,7 @@ class GeometryAnalyzer:
return features return features
def _detect_fillet_features(self, shape: Any) -> List[Dict[str, Any]]: def _detect_fillet_features(self, shape: TopoDS_Shape) -> List[Dict[str, Any]]:
"""检测圆角/倒角特征""" """检测圆角/倒角特征"""
features = [] features = []
try: try:
+3 -2
View File
@@ -8,6 +8,7 @@ from OCC.Core.BRepMesh import BRepMesh_IncrementalMesh
from OCC.Core.TopExp import TopExp_Explorer from OCC.Core.TopExp import TopExp_Explorer
from OCC.Core.TopAbs import TopAbs_FACE from OCC.Core.TopAbs import TopAbs_FACE
from OCC.Core.BRep import BRep_Tool from OCC.Core.BRep import BRep_Tool
from OCC.Core.TopoDS import TopoDS_Shape
from OCC.Core.TopLoc import TopLoc_Location from OCC.Core.TopLoc import TopLoc_Location
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -24,7 +25,7 @@ class MeshGenerator:
} }
self.quality = self.quality_settings.get(quality, 0.3) self.quality = self.quality_settings.get(quality, 0.3)
def generate_mesh_from_shape(self, shape, num_points: int = 20000) -> Dict: def generate_mesh_from_shape(self, shape: TopoDS_Shape, num_points: int = 20000) -> Dict:
"""从PythonOCC形状生成点云数据""" """从PythonOCC形状生成点云数据"""
try: try:
mesh = BRepMesh_IncrementalMesh(shape, self.quality, False, 0.5, True) mesh = BRepMesh_IncrementalMesh(shape, self.quality, False, 0.5, True)
@@ -121,7 +122,7 @@ class MeshGenerator:
logger.error(traceback.format_exc()) logger.error(traceback.format_exc())
return self._create_sample_pointcloud() return self._create_sample_pointcloud()
def generate_multi_lod_mesh(self, shape) -> Dict: def generate_multi_lod_mesh(self, shape: TopoDS_Shape) -> Dict:
"""生成多级LOD网格 - 一次OCC剖分,trimesh简化,避免重复计算 """生成多级LOD网格 - 一次OCC剖分,trimesh简化,避免重复计算
返回结构: 返回结构:
+9 -9
View File
@@ -2,7 +2,7 @@ from typing import Dict, List, Any, Tuple, Optional
import numpy as np import numpy as np
from OCC.Core.BRepBuilderAPI import BRepBuilderAPI_MakeFace from OCC.Core.BRepBuilderAPI import BRepBuilderAPI_MakeFace
from OCC.Core.gp import gp_Pln, gp_Dir, gp_Pnt from OCC.Core.gp import gp_Pln, gp_Dir, gp_Pnt
from OCC.Core.TopoDS import TopoDS_Face, topods from OCC.Core.TopoDS import TopoDS_Face, TopoDS_Shape, topods
from OCC.Core.BRepAdaptor import BRepAdaptor_Surface from OCC.Core.BRepAdaptor import BRepAdaptor_Surface
from OCC.Core.TopExp import TopExp_Explorer from OCC.Core.TopExp import TopExp_Explorer
from OCC.Core.TopAbs import TopAbs_FACE from OCC.Core.TopAbs import TopAbs_FACE
@@ -47,7 +47,7 @@ class MoldCavityGenerator(BaseMoldGenerator):
else: else:
logger.warning(f"未知材料 {material}, 使用默认密度 {self.material_density} g/cm³") logger.warning(f"未知材料 {material}, 使用默认密度 {self.material_density} g/cm³")
def generate_mold_cavities(self, product_shape: Any) -> Dict[str, Any]: def generate_mold_cavities(self, product_shape: TopoDS_Shape) -> Dict[str, Any]:
""" """
从产品的3D模型生成型腔和型芯 从产品的3D模型生成型腔和型芯
@@ -196,7 +196,7 @@ class MoldCavityGenerator(BaseMoldGenerator):
# ==================== 内部方法 ==================== # ==================== 内部方法 ====================
def _detect_parting_surface(self, shape: Any, analysis: Dict) -> Tuple[Any, List]: def _detect_parting_surface(self, shape: TopoDS_Shape, analysis: Dict) -> Tuple[TopoDS_Face, List]:
""" """
检测分型面和分型线 检测分型面和分型线
@@ -219,7 +219,7 @@ class MoldCavityGenerator(BaseMoldGenerator):
logger.info("使用简化方法检测分型面") logger.info("使用简化方法检测分型面")
return self._simple_parting_surface(shape, analysis) return self._simple_parting_surface(shape, analysis)
def _detect_primary_parting(self, shape: Any, analysis: Dict) -> Dict[str, Any]: def _detect_primary_parting(self, shape: TopoDS_Shape, analysis: Dict) -> Dict[str, Any]:
"""检测主分型面(AI优先 → 几何法向量 → 简化回退)""" """检测主分型面(AI优先 → 几何法向量 → 简化回退)"""
if self.ai_parting_detector is not None: if self.ai_parting_detector is not None:
try: try:
@@ -283,7 +283,7 @@ class MoldCavityGenerator(BaseMoldGenerator):
logger.info(f"转换得到 {len(regions)} 个兼容倒扣区域") logger.info(f"转换得到 {len(regions)} 个兼容倒扣区域")
return regions return regions
def _analyze_face_normals(self, shape: Any) -> gp_Dir: def _analyze_face_normals(self, shape: TopoDS_Shape) -> gp_Dir:
""" """
分析产品表面的法向量分布,找出最优分型方向 分析产品表面的法向量分布,找出最优分型方向
@@ -326,7 +326,7 @@ class MoldCavityGenerator(BaseMoldGenerator):
else: else:
return gp_Dir(0, 0, 1) return gp_Dir(0, 0, 1)
def _create_optimal_parting_plane(self, shape: Any, analysis: Dict, def _create_optimal_parting_plane(self, shape: TopoDS_Shape, analysis: Dict,
direction: gp_Dir) -> gp_Pln: direction: gp_Dir) -> gp_Pln:
""" """
创建最优分型面 创建最优分型面
@@ -352,7 +352,7 @@ class MoldCavityGenerator(BaseMoldGenerator):
return parting_plane return parting_plane
def _simple_parting_surface(self, shape: Any, analysis: Dict) -> Tuple[Any, List]: def _simple_parting_surface(self, shape: TopoDS_Shape, analysis: Dict) -> Tuple[TopoDS_Face, List]:
"""简化的分型面检测(回退方案)""" """简化的分型面检测(回退方案)"""
bbox = analysis["bounding_box"] bbox = analysis["bounding_box"]
center_z = bbox["center"][2] center_z = bbox["center"][2]
@@ -372,7 +372,7 @@ class MoldCavityGenerator(BaseMoldGenerator):
return parting_surface, parting_line return parting_surface, parting_line
def _create_parting_surface_from_ai(self, ai_result: Dict, def _create_parting_surface_from_ai(self, ai_result: Dict,
analysis: Dict, shape: Any = None) -> Tuple[Any, List]: analysis: Dict, shape: Optional[TopoDS_Shape] = None) -> Tuple[TopoDS_Face, List]:
""" """
从 AI 模型结果创建分型面(预留接口) 从 AI 模型结果创建分型面(预留接口)
@@ -405,7 +405,7 @@ class MoldCavityGenerator(BaseMoldGenerator):
logger.info(f"从 AI 结果创建分型面:原点={origin}, 法向量={normal}") logger.info(f"从 AI 结果创建分型面:原点={origin}, 法向量={normal}")
return parting_surface, parting_line return parting_surface, parting_line
def _extract_parting_surface_geometry(self, surface: Any) -> Dict[str, Any]: def _extract_parting_surface_geometry(self, surface: TopoDS_Face) -> Dict[str, Any]:
"""提取分型面几何数据""" """提取分型面几何数据"""
metadata = self._extract_plane_metadata(surface) metadata = self._extract_plane_metadata(surface)
+6 -6
View File
@@ -6,7 +6,7 @@ from OCC.Core.GProp import GProp_GProps
from OCC.Core.gp import gp_Dir, gp_Pln, gp_Pnt from OCC.Core.gp import gp_Dir, gp_Pln, gp_Pnt
from OCC.Core.TopAbs import TopAbs_FACE from OCC.Core.TopAbs import TopAbs_FACE
from OCC.Core.TopExp import TopExp_Explorer from OCC.Core.TopExp import TopExp_Explorer
from OCC.Core.TopoDS import TopoDS_Face, topods from OCC.Core.TopoDS import TopoDS_Face, TopoDS_Shape, topods
from core.mold_generator import MoldCavityGenerator from core.mold_generator import MoldCavityGenerator
from core.aluminum_foam_mold import AluminumFoamMoldGenerator from core.aluminum_foam_mold import AluminumFoamMoldGenerator
@@ -31,7 +31,7 @@ class MultiSchemeMoldPlanner:
def generate_plan( def generate_plan(
self, self,
shape: Any, shape: TopoDS_Shape,
material: Dict[str, Any], material: Dict[str, Any],
is_foam_material: bool = False, is_foam_material: bool = False,
max_schemes: int = 3, max_schemes: int = 3,
@@ -92,7 +92,7 @@ class MultiSchemeMoldPlanner:
def _build_scheme( def _build_scheme(
self, self,
generator: Any, generator: Any,
shape: Any, shape: TopoDS_Shape,
analysis: Dict[str, Any], analysis: Dict[str, Any],
candidate: Dict[str, Any], candidate: Dict[str, Any],
is_foam_material: bool, is_foam_material: bool,
@@ -209,10 +209,10 @@ class MultiSchemeMoldPlanner:
generator: Any, generator: Any,
analysis: Dict[str, Any], analysis: Dict[str, Any],
direction_vector: List[float], direction_vector: List[float],
shape: Any, shape: TopoDS_Shape,
offset_ratio: float = 0.0, offset_ratio: float = 0.0,
opening_span_mm: Optional[float] = None, opening_span_mm: Optional[float] = None,
) -> Any: ) -> TopoDS_Face:
center = analysis.get("bounding_box", {}).get("center", [0, 0, 0]) center = analysis.get("bounding_box", {}).get("center", [0, 0, 0])
dims = analysis.get("bounding_box", {}).get("dimensions", [100, 100, 100]) dims = analysis.get("bounding_box", {}).get("dimensions", [100, 100, 100])
span = max(dims) * 1.5 + 30 span = max(dims) * 1.5 + 30
@@ -272,7 +272,7 @@ class MultiSchemeMoldPlanner:
return variants return variants
def _collect_axis_normal_stats(self, generator: Any, shape: Any) -> Dict[str, float]: def _collect_axis_normal_stats(self, generator: Any, shape: TopoDS_Shape) -> Dict[str, float]:
"""按坐标轴统计面法向分布强度,用于候选方向排序。""" """按坐标轴统计面法向分布强度,用于候选方向排序。"""
stats = {"X": 0.0, "Y": 0.0, "Z": 0.0} stats = {"X": 0.0, "Y": 0.0, "Z": 0.0}
explorer = TopExp_Explorer(shape, TopAbs_FACE) explorer = TopExp_Explorer(shape, TopAbs_FACE)
+5 -4
View File
@@ -21,6 +21,7 @@
from typing import Dict, List, Any, Optional, Tuple from typing import Dict, List, Any, Optional, Tuple
import math import math
import numpy as np import numpy as np
from OCC.Core.TopoDS import TopoDS_Shape, TopoDS_Face
from utils.logger import get_logger from utils.logger import get_logger
logger = get_logger(__name__) logger = get_logger(__name__)
@@ -29,8 +30,8 @@ logger = get_logger(__name__)
class UndercutDetector: class UndercutDetector:
"""倒扣区域检测器""" """倒扣区域检测器"""
def detect_undercuts(self, shape: Any, parting_direction: List[float], def detect_undercuts(self, shape: TopoDS_Shape, parting_direction: List[float],
parting_surface: Any = None) -> Dict[str, Any]: parting_surface: Optional[TopoDS_Face] = None) -> Dict[str, Any]:
""" """
检测产品中的倒扣区域 检测产品中的倒扣区域
@@ -443,8 +444,8 @@ class SideActionDesigner:
self.slider_designer = SliderMechanismDesigner() self.slider_designer = SliderMechanismDesigner()
self.lifter_designer = LifterMechanismDesigner() self.lifter_designer = LifterMechanismDesigner()
def analyze_and_design(self, shape: Any, parting_direction: List[float], def analyze_and_design(self, shape: TopoDS_Shape, parting_direction: List[float],
mold_size: Dict, parting_surface: Any = None) -> Dict[str, Any]: mold_size: Dict, parting_surface: Optional[TopoDS_Face] = None) -> Dict[str, Any]:
""" """
综合分析倒扣并设计侧向分型机构 综合分析倒扣并设计侧向分型机构
+9 -8
View File
@@ -6,6 +6,7 @@ import json
from utils.logger import get_logger from utils.logger import get_logger
from OCC.Core.GProp import GProp_GProps from OCC.Core.GProp import GProp_GProps
from OCC.Core.BRepGProp import brepgprop from OCC.Core.BRepGProp import brepgprop
from OCC.Core.TopoDS import TopoDS_Shape
logger = get_logger(__name__) logger = get_logger(__name__)
@@ -29,7 +30,7 @@ class STPParser:
def load_step_file(self, file_path: Path) -> Any: def load_step_file(self, file_path: Path) -> TopoDS_Shape:
"""加载STP文件""" """加载STP文件"""
try: try:
from OCC.Core.STEPControl import STEPControl_Reader from OCC.Core.STEPControl import STEPControl_Reader
@@ -51,7 +52,7 @@ class STPParser:
logger.error(f"STP解析失败: {e}") logger.error(f"STP解析失败: {e}")
raise raise
def analyze_geometry(self, shape) -> Dict[str, Any]: def analyze_geometry(self, shape: TopoDS_Shape) -> Dict[str, Any]:
"""分析几何属性""" """分析几何属性"""
try: try:
@@ -97,7 +98,7 @@ class STPParser:
logger.error(f"几何分析失败: {e}") logger.error(f"几何分析失败: {e}")
raise raise
def _compute_bounding_box(self, shape) -> Dict[str, Any]: def _compute_bounding_box(self, shape: TopoDS_Shape) -> Dict[str, Any]:
"""计算边界框""" """计算边界框"""
try: try:
from OCC.Core.Bnd import Bnd_Box from OCC.Core.Bnd import Bnd_Box
@@ -125,7 +126,7 @@ class STPParser:
logger.error(f"边界框计算失败: {e}") logger.error(f"边界框计算失败: {e}")
return self._default_bounding_box() return self._default_bounding_box()
def _compute_volume(self, shape) -> float: def _compute_volume(self, shape: TopoDS_Shape) -> float:
"""计算体积""" """计算体积"""
try: try:
from OCC.Core.GProp import GProp_GProps from OCC.Core.GProp import GProp_GProps
@@ -141,7 +142,7 @@ class STPParser:
logger.error(f"体积计算失败: {e}") logger.error(f"体积计算失败: {e}")
raise RuntimeError(f"体积计算失败: {e}") from e raise RuntimeError(f"体积计算失败: {e}") from e
def _compute_surface_area(self, shape) -> float: def _compute_surface_area(self, shape: TopoDS_Shape) -> float:
"""计算表面积""" """计算表面积"""
try: try:
from OCC.Core.GProp import GProp_GProps from OCC.Core.GProp import GProp_GProps
@@ -175,7 +176,7 @@ class STPParser:
logger.error(f"表面积计算失败: {e}") logger.error(f"表面积计算失败: {e}")
raise RuntimeError(f"表面积计算失败: {e}") from e raise RuntimeError(f"表面积计算失败: {e}") from e
def _compute_center_of_mass(self, shape) -> List[float]: def _compute_center_of_mass(self, shape: TopoDS_Shape) -> List[float]:
"""计算质心""" """计算质心"""
try: try:
from OCC.Core.GProp import GProp_GProps from OCC.Core.GProp import GProp_GProps
@@ -194,7 +195,7 @@ class STPParser:
except Exception: except Exception:
raise RuntimeError(f"质心计算失败且边界框回退也失败: {e}") from e raise RuntimeError(f"质心计算失败且边界框回退也失败: {e}") from e
def _compute_inertia_properties(self, shape) -> Dict[str, Any]: def _compute_inertia_properties(self, shape: TopoDS_Shape) -> Dict[str, Any]:
"""计算惯性属性""" """计算惯性属性"""
try: try:
from OCC.Core.GProp import GProp_GProps from OCC.Core.GProp import GProp_GProps
@@ -216,7 +217,7 @@ class STPParser:
logger.error(f"惯性属性计算失败: {e}") logger.error(f"惯性属性计算失败: {e}")
return {} return {}
def _analyze_topology(self, shape) -> Dict[str, int]: def _analyze_topology(self, shape: TopoDS_Shape) -> Dict[str, int]:
"""分析拓扑""" """分析拓扑"""
try: try:
from OCC.Core.TopExp import TopExp_Explorer from OCC.Core.TopExp import TopExp_Explorer