init
This commit is contained in:
+353
-1
@@ -3,6 +3,7 @@ from fastapi import APIRouter, UploadFile, File, HTTPException, BackgroundTasks,
|
||||
from typing import Optional, Dict, Any, List
|
||||
import uuid
|
||||
from datetime import datetime
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
from models.schemas import ProcessingStatus, create_task_info
|
||||
@@ -18,6 +19,12 @@ from core.mold_generator import MoldCavityGenerator
|
||||
from core.aluminum_foam_mold import AluminumFoamMoldGenerator
|
||||
from core.mold_quality_inspector import AluminumFoamMoldQualityInspector
|
||||
from core.mesh_generator import MeshGenerator
|
||||
from core.cavity_layout_optimizer import CavityLayoutOptimizer
|
||||
from core.mold_system_designer import MoldSystemDesigner
|
||||
from core.side_action_designer import SideActionDesigner
|
||||
from core.mold_cam import MoldCAMDesigner
|
||||
from core.mold_machining import CollisionDetector, ToolpathOptimizer, EDMElectrodeDesigner, MachiningSimulator
|
||||
from core.cad_exporter import CADExporter
|
||||
from services.auth_service import get_current_active_user
|
||||
from models.database import User
|
||||
|
||||
@@ -35,6 +42,15 @@ aluminum_foam_generator = AluminumFoamMoldGenerator(shrinkage_rate=0.015, draft_
|
||||
# 铝泡沫模具质量检测器
|
||||
mold_quality_inspector = AluminumFoamMoldQualityInspector()
|
||||
mesh_generator = MeshGenerator(quality="medium")
|
||||
cavity_layout_optimizer = CavityLayoutOptimizer()
|
||||
mold_system_designer = MoldSystemDesigner()
|
||||
side_action_designer = SideActionDesigner()
|
||||
mold_cam_designer = MoldCAMDesigner()
|
||||
collision_detector = CollisionDetector()
|
||||
toolpath_optimizer = ToolpathOptimizer()
|
||||
edm_designer = EDMElectrodeDesigner()
|
||||
machining_simulator = MachiningSimulator()
|
||||
cad_exporter = CADExporter()
|
||||
|
||||
tasks = {}
|
||||
|
||||
@@ -348,6 +364,341 @@ async def process_file_with_storage(
|
||||
tasks[task_id]["completed_at"] = str(datetime.now())
|
||||
|
||||
|
||||
# ==================== P3 新增 API ====================
|
||||
|
||||
@router.post("/optimize-layout")
|
||||
async def optimize_cavity_layout(
|
||||
request: Request,
|
||||
current_user: User = Depends(get_current_active_user),
|
||||
):
|
||||
"""多型腔布局优化"""
|
||||
body = await request.json()
|
||||
product_bbox = body.get("product_bbox", {"dimensions": [100, 100, 50]})
|
||||
cavity_count = body.get("cavity_count", 1)
|
||||
mold_base_size = body.get("mold_base_size")
|
||||
layout_type = body.get("layout_type", "auto")
|
||||
|
||||
if cavity_count < 1 or cavity_count > 64:
|
||||
raise HTTPException(400, "型腔数量必须在 1-64 之间")
|
||||
|
||||
result = cavity_layout_optimizer.optimize_layout(
|
||||
product_bbox=product_bbox,
|
||||
cavity_count=cavity_count,
|
||||
mold_base_size=mold_base_size,
|
||||
layout_type=layout_type,
|
||||
)
|
||||
|
||||
return {"status": "success", "data": result}
|
||||
|
||||
|
||||
@router.post("/design-cooling")
|
||||
async def design_cooling_system(
|
||||
request: Request,
|
||||
current_user: User = Depends(get_current_active_user),
|
||||
):
|
||||
"""冷却系统设计"""
|
||||
body = await request.json()
|
||||
mold_size = body.get("mold_size", {"length": 300, "width": 300, "height": 200})
|
||||
product_bbox = body.get("product_bbox", {"dimensions": [100, 100, 50]})
|
||||
material = body.get("material", "ABS")
|
||||
cavity_count = body.get("cavity_count", 1)
|
||||
cycle_time_target = body.get("cycle_time_target")
|
||||
|
||||
from core.mold_system_designer import CoolingSystemDesigner
|
||||
designer = CoolingSystemDesigner()
|
||||
result = designer.design_cooling_system(
|
||||
mold_size=mold_size,
|
||||
product_bbox=product_bbox,
|
||||
material=material,
|
||||
cavity_count=cavity_count,
|
||||
cycle_time_target=cycle_time_target,
|
||||
)
|
||||
|
||||
return {"status": "success", "data": result}
|
||||
|
||||
|
||||
@router.post("/design-gating")
|
||||
async def design_gating_system(
|
||||
request: Request,
|
||||
current_user: User = Depends(get_current_active_user),
|
||||
):
|
||||
"""浇注系统设计"""
|
||||
body = await request.json()
|
||||
product_bbox = body.get("product_bbox", {"dimensions": [100, 100, 50]})
|
||||
material = body.get("material", "ABS")
|
||||
cavity_count = body.get("cavity_count", 1)
|
||||
gate_type = body.get("gate_type", "auto")
|
||||
layout_positions = body.get("layout_positions")
|
||||
|
||||
from core.mold_system_designer import GatingSystemDesigner
|
||||
designer = GatingSystemDesigner()
|
||||
result = designer.design_gating_system(
|
||||
product_bbox=product_bbox,
|
||||
material=material,
|
||||
cavity_count=cavity_count,
|
||||
gate_type=gate_type,
|
||||
layout_positions=layout_positions,
|
||||
)
|
||||
|
||||
return {"status": "success", "data": result}
|
||||
|
||||
|
||||
@router.post("/design-mold-system")
|
||||
async def design_complete_mold_system(
|
||||
request: Request,
|
||||
current_user: User = Depends(get_current_active_user),
|
||||
):
|
||||
"""综合模具系统设计(冷却+浇注)"""
|
||||
body = await request.json()
|
||||
mold_size = body.get("mold_size", {"length": 300, "width": 300, "height": 200})
|
||||
product_bbox = body.get("product_bbox", {"dimensions": [100, 100, 50]})
|
||||
material = body.get("material", "ABS")
|
||||
cavity_count = body.get("cavity_count", 1)
|
||||
gate_type = body.get("gate_type", "auto")
|
||||
cycle_time_target = body.get("cycle_time_target")
|
||||
layout_positions = body.get("layout_positions")
|
||||
|
||||
result = mold_system_designer.design_complete_system(
|
||||
mold_size=mold_size,
|
||||
product_bbox=product_bbox,
|
||||
material=material,
|
||||
cavity_count=cavity_count,
|
||||
gate_type=gate_type,
|
||||
cycle_time_target=cycle_time_target,
|
||||
layout_positions=layout_positions,
|
||||
)
|
||||
|
||||
return {"status": "success", "data": result}
|
||||
|
||||
|
||||
@router.post("/ai-parting-detect")
|
||||
async def ai_parting_surface_detect(
|
||||
request: Request,
|
||||
current_user: User = Depends(get_current_active_user),
|
||||
):
|
||||
"""AI 分型面检测"""
|
||||
body = await request.json()
|
||||
task_id = body.get("task_id")
|
||||
|
||||
if not task_id or task_id not in tasks:
|
||||
raise HTTPException(404, "任务不存在")
|
||||
|
||||
task_data = tasks[task_id]
|
||||
geometry_data = task_data.get("geometry_data")
|
||||
if not geometry_data:
|
||||
raise HTTPException(400, "该任务尚未完成几何分析")
|
||||
|
||||
from core.ai_parting_detector import AIPartingSurfaceDetectorV2
|
||||
detector = AIPartingSurfaceDetectorV2(use_gnn=True)
|
||||
|
||||
result = detector._detect_with_geometry(None, geometry_data)
|
||||
|
||||
return {"status": "success", "data": result}
|
||||
|
||||
|
||||
@router.post("/detect-undercuts")
|
||||
async def detect_undercuts(
|
||||
request: Request,
|
||||
current_user: User = Depends(get_current_active_user),
|
||||
):
|
||||
"""倒扣区域检测与滑块/斜顶机构设计"""
|
||||
body = await request.json()
|
||||
task_id = body.get("task_id")
|
||||
parting_direction = body.get("parting_direction", [0, 0, 1])
|
||||
mold_size = body.get("mold_size", {"length": 300, "width": 300, "height": 200})
|
||||
|
||||
if not task_id or task_id not in tasks:
|
||||
raise HTTPException(404, "任务不存在")
|
||||
|
||||
task_data = tasks[task_id]
|
||||
geometry_data = task_data.get("geometry_data")
|
||||
if not geometry_data:
|
||||
raise HTTPException(400, "该任务尚未完成几何分析")
|
||||
|
||||
result = side_action_designer.analyze_and_design(
|
||||
shape=None, parting_direction=parting_direction, mold_size=mold_size
|
||||
)
|
||||
|
||||
return {"status": "success", "data": result}
|
||||
|
||||
|
||||
@router.post("/design-cam")
|
||||
async def design_mold_cam(
|
||||
request: Request,
|
||||
current_user: User = Depends(get_current_active_user),
|
||||
):
|
||||
"""模具CAM刀路设计"""
|
||||
body = await request.json()
|
||||
cavity_bbox = body.get("cavity_bbox", {"dimensions": [100, 100, 50], "min": [-50, -50, -25], "max": [50, 50, 25]})
|
||||
stock_bbox = body.get("stock_bbox", {"dimensions": [150, 150, 100], "min": [-75, -75, -50], "max": [75, 75, 50]})
|
||||
mold_steel = body.get("mold_steel", "P20")
|
||||
surface_quality = body.get("surface_quality", "standard")
|
||||
controller = body.get("controller", "fanuc")
|
||||
|
||||
result = mold_cam_designer.design_mold_cam(
|
||||
cavity_bbox=cavity_bbox,
|
||||
stock_bbox=stock_bbox,
|
||||
mold_steel=mold_steel,
|
||||
surface_quality=surface_quality,
|
||||
controller=controller,
|
||||
)
|
||||
|
||||
return {"status": "success", "data": result}
|
||||
|
||||
|
||||
@router.post("/check-collision")
|
||||
async def check_toolpath_collision(
|
||||
request: Request,
|
||||
current_user: User = Depends(get_current_active_user),
|
||||
):
|
||||
"""刀路碰撞检测"""
|
||||
body = await request.json()
|
||||
toolpath_points = body.get("toolpath_points", [[0, 0, 50], [10, 10, -5], [20, 20, -10]])
|
||||
tool = body.get("tool", {"diameter": 10, "flute_length": 30, "shank_diameter": 10})
|
||||
stock_bbox = body.get("stock_bbox", {"min": [-50, -50, -25], "max": [50, 50, 25]})
|
||||
clamp_positions = body.get("clamp_positions")
|
||||
|
||||
result = collision_detector.check_toolpath_safety(
|
||||
toolpath_points, tool, stock_bbox, clamp_positions
|
||||
)
|
||||
|
||||
return {"status": "success", "data": result}
|
||||
|
||||
|
||||
@router.post("/optimize-toolpath")
|
||||
async def optimize_toolpath(
|
||||
request: Request,
|
||||
current_user: User = Depends(get_current_active_user),
|
||||
):
|
||||
"""刀路优化"""
|
||||
body = await request.json()
|
||||
toolpath_points = body.get("toolpath_points", [[0, 0, 50], [10, 10, -5], [20, 20, -10]])
|
||||
cutting_params = body.get("cutting_params", {"feed_rate_mm_min": 500})
|
||||
stock_bbox = body.get("stock_bbox")
|
||||
|
||||
result = toolpath_optimizer.optimize_toolpath(
|
||||
toolpath_points, cutting_params, stock_bbox
|
||||
)
|
||||
|
||||
return {"status": "success", "data": result}
|
||||
|
||||
|
||||
@router.post("/design-electrodes")
|
||||
async def design_edm_electrodes(
|
||||
request: Request,
|
||||
current_user: User = Depends(get_current_active_user),
|
||||
):
|
||||
"""EDM电极设计"""
|
||||
body = await request.json()
|
||||
undercut_regions = body.get("undercut_regions", [{"center": [0, 0, 0], "area": 100, "type": "undercut"}])
|
||||
cavity_bbox = body.get("cavity_bbox", {"dimensions": [100, 100, 50]})
|
||||
material = body.get("material", "copper")
|
||||
spark_gap = body.get("spark_gap", 0.05)
|
||||
overburn = body.get("overburn", 0.1)
|
||||
|
||||
result = edm_designer.design_electrodes(
|
||||
undercut_regions, cavity_bbox, material, spark_gap, overburn
|
||||
)
|
||||
|
||||
return {"status": "success", "data": result}
|
||||
|
||||
|
||||
@router.post("/simulate-machining")
|
||||
async def simulate_machining(
|
||||
request: Request,
|
||||
current_user: User = Depends(get_current_active_user),
|
||||
):
|
||||
"""加工仿真"""
|
||||
body = await request.json()
|
||||
operations = body.get("operations", [{"strategy": "z_level_roughing", "levels": [{"z": -5}]}])
|
||||
stock_bbox = body.get("stock_bbox", {"dimensions": [100, 100, 50], "min": [-50, -50, -25], "max": [50, 50, 25]})
|
||||
resolution = body.get("resolution", 2.0)
|
||||
|
||||
result = machining_simulator.simulate_machining(
|
||||
operations, stock_bbox, resolution
|
||||
)
|
||||
|
||||
return {"status": "success", "data": result}
|
||||
|
||||
|
||||
# ==================== CAD 导出 API ====================
|
||||
|
||||
@router.post("/export-mold")
|
||||
async def export_mold_results(
|
||||
request: Request,
|
||||
current_user: User = Depends(get_current_active_user),
|
||||
):
|
||||
"""导出模具设计结果(STEP/IGES/STL/BRep)"""
|
||||
body = await request.json()
|
||||
task_id = body.get("task_id")
|
||||
formats = body.get("formats", ["step", "stl"])
|
||||
components = body.get("components", ["cavity", "core"])
|
||||
|
||||
if not task_id or task_id not in tasks:
|
||||
raise HTTPException(404, "任务不存在")
|
||||
|
||||
task_data = tasks[task_id]
|
||||
cavity_shapes = task_data.get("cavity_shapes")
|
||||
if not cavity_shapes:
|
||||
raise HTTPException(400, "该任务尚未完成模具生成或形状数据不可用")
|
||||
|
||||
base_filename = Path(task_data.get("filename", f"mold_{task_id}")).stem
|
||||
|
||||
result = cad_exporter.export_mold_results(
|
||||
cavity_data=cavity_shapes,
|
||||
base_filename=base_filename,
|
||||
formats=formats,
|
||||
components=components,
|
||||
)
|
||||
|
||||
return {"status": "success", "data": result}
|
||||
|
||||
|
||||
@router.get("/export-download/{filepath:path}")
|
||||
async def download_export_file(
|
||||
filepath: str,
|
||||
current_user: User = Depends(get_current_active_user),
|
||||
):
|
||||
"""下载导出的CAD文件"""
|
||||
from fastapi.responses import FileResponse
|
||||
|
||||
full_path = os.path.join(cad_exporter.output_dir, filepath)
|
||||
|
||||
if not os.path.exists(full_path):
|
||||
raise HTTPException(404, "文件不存在")
|
||||
|
||||
if not os.path.abspath(full_path).startswith(os.path.abspath(cad_exporter.output_dir)):
|
||||
raise HTTPException(403, "禁止访问")
|
||||
|
||||
media_types = {
|
||||
".step": "application/step",
|
||||
".stp": "application/step",
|
||||
".iges": "application/iges",
|
||||
".igs": "application/iges",
|
||||
".stl": "model/stl",
|
||||
".brep": "application/octet-stream",
|
||||
}
|
||||
|
||||
ext = Path(full_path).suffix.lower()
|
||||
media_type = media_types.get(ext, "application/octet-stream")
|
||||
|
||||
return FileResponse(
|
||||
full_path,
|
||||
media_type=media_type,
|
||||
filename=os.path.basename(full_path),
|
||||
)
|
||||
|
||||
|
||||
@router.get("/export-recommendations")
|
||||
async def get_export_recommendations(
|
||||
target: str = "ug",
|
||||
current_user: User = Depends(get_current_active_user),
|
||||
):
|
||||
"""获取导出格式建议(UG/FreeCAD/SolidWorks)"""
|
||||
result = cad_exporter.get_export_recommendations(target)
|
||||
return {"status": "success", "data": result}
|
||||
|
||||
|
||||
async def _save_analysis_metrics(session, stp_file_id, analysis_result):
|
||||
"""保存分析指标到数据库"""
|
||||
from models.database import AnalysisMetrics
|
||||
@@ -774,7 +1125,7 @@ async def process_file_core(
|
||||
)
|
||||
|
||||
# 9. 分析模具设计
|
||||
analysis_result = geometry_analyzer.analyze_mold_design(geometry_data)
|
||||
analysis_result = geometry_analyzer.analyze_mold_design(geometry_data, shape=shape)
|
||||
|
||||
# 9.5 保存完整的分析结果到数据库
|
||||
if analysis_result:
|
||||
@@ -838,6 +1189,7 @@ async def process_file_core(
|
||||
tasks[task_id]["geometry_data"] = geometry_data
|
||||
tasks[task_id]["analysis_result"] = analysis_result
|
||||
tasks[task_id]["cavity_data"] = detailed_cavity_json
|
||||
tasks[task_id]["cavity_shapes"] = cavity_result
|
||||
tasks[task_id]["key_info"] = detailed_cavity_json # 传递完整数据给前端
|
||||
tasks[task_id]["html_file"] = f"/html/{Path(html_file_path).name}" # 只使用文件名
|
||||
tasks[task_id]["verification"] = verification_result # 添加验证结果
|
||||
|
||||
Reference in New Issue
Block a user