分模候选方案

This commit is contained in:
2026-04-23 23:57:34 +08:00
parent c1f6b6e827
commit f9acdb767b
5 changed files with 94 additions and 35 deletions
+23 -12
View File
@@ -1,16 +1,27 @@
from fastapi import APIRouter
import importlib
from api.v1.health_router import router as health_router
from api.v1.upload_router import router as upload_router
from api.v1.task_router import router as task_router
from api.v1.history_router import router as history_router
from api.v1.debug_router import router as debug_router
from api.v1.advanced_router import router as advanced_router
from utils.logger import get_logger
logger = get_logger(__name__)
router = APIRouter()
router.include_router(health_router)
router.include_router(upload_router)
router.include_router(task_router)
router.include_router(history_router)
router.include_router(debug_router)
router.include_router(advanced_router)
def _safe_include(module_path: str, label: str):
try:
module = importlib.import_module(module_path)
router_obj = getattr(module, "router", None)
if router_obj is None:
raise ValueError("未找到 router 对象")
router.include_router(router_obj)
logger.info(f"{label} 路由加载成功")
except Exception as exc:
logger.warning(f"{label} 路由加载失败,已跳过: {exc}")
_safe_include("api.v1.health_router", "健康检查")
_safe_include("api.v1.upload_router", "上传")
_safe_include("api.v1.task_router", "任务")
_safe_include("api.v1.history_router", "历史")
_safe_include("api.v1.debug_router", "调试")
_safe_include("api.v1.advanced_router", "高级")
-2
View File
@@ -15,7 +15,6 @@ from sqlalchemy.ext.asyncio import AsyncSession
from services.auth_service import get_current_active_user
from services.processing_service import processing_service
from models.database import User
from api.routes import tasks as legacy_tasks
logger = get_logger(__name__)
@@ -66,7 +65,6 @@ async def upload_stp(
upload_time=str(datetime.now())
)
await redis_task_manager.set_task(task_id, task_info)
legacy_tasks[task_id] = task_info
# 后台处理(使用独立数据库会话,避免请求会话关闭问题)
background_tasks.add_task(
+7 -3
View File
@@ -67,9 +67,13 @@ class MeshGenerator:
face_vertices = []
for i in range(1, nb_nodes + 1):
pnt = face_triangulation.Node(i)
# 应用位置变换
pnt.Transform(trsf)
face_vertices.append([float(pnt.X()), float(pnt.Y()), float(pnt.Z())])
# 使用变换后的拷贝点,避免潜在的原地变换副作用
transformed = pnt.Transformed(trsf)
face_vertices.append([
float(transformed.X()),
float(transformed.Y()),
float(transformed.Z()),
])
# 提取三角形索引
face_indices = []
+9 -1
View File
@@ -127,7 +127,15 @@ try:
from api.v1 import router as moldinsight_router
except Exception as e:
moldinsight_router = None
print(f"[WARN] MoldInsight路由未加载: {e}")
print(f"[WARN] MoldInsight v1路由未加载: {e}")
if moldinsight_router is None:
try:
from api.routes import router as moldinsight_router
print("[WARN] 已回退到旧版 MoldInsight 路由")
except Exception as fallback_error:
moldinsight_router = None
print(f"[WARN] MoldInsight旧版路由也未加载: {fallback_error}")
if moldinsight_router is not None:
app.include_router(moldinsight_router, prefix="/api")
+55 -17
View File
@@ -221,9 +221,49 @@ class HTMLGenerator:
const cavityData = {json.dumps(cavity_data, indent=2) if cavity_data else 'null'};
const pointcloudData = {json.dumps(pointcloud_data, indent=2) if pointcloud_data else 'null'};
function toFlatArray(data) {{
if (!Array.isArray(data)) return [];
if (data.length === 0) return [];
return Array.isArray(data[0]) ? data.flat() : data;
}}
function normalizePositions(rawPositions, center) {{
const flat = toFlatArray(rawPositions);
if (!flat.length) return [];
const normalized = [];
for (let i = 0; i + 2 < flat.length; i += 3) {{
const x = Number(flat[i]);
const y = Number(flat[i + 1]);
const z = Number(flat[i + 2]);
if (Number.isFinite(x) && Number.isFinite(y) && Number.isFinite(z)) {{
normalized.push(
x - Number(center[0] || 0),
y - Number(center[1] || 0),
z - Number(center[2] || 0)
);
}}
}}
return normalized;
}}
function fitCameraToScene() {{
const sceneBox = new THREE.Box3().setFromObject(scene);
if (sceneBox.isEmpty()) return;
const center = new THREE.Vector3();
const size = new THREE.Vector3();
sceneBox.getCenter(center);
sceneBox.getSize(size);
const maxDim = Math.max(size.x, size.y, size.z) || 100;
const distance = maxDim * 2.2;
camera.position.set(center.x + distance, center.y + distance, center.z + distance);
controls.target.copy(center);
controls.update();
}}
// 根据边界框创建几何体
const bbox = geometryData.bounding_box;
if (bbox) {{
const centerOffset = bbox.center || [0, 0, 0];
const width = bbox.dimensions ? bbox.dimensions[0] : 100;
const height = bbox.dimensions ? bbox.dimensions[1] : 100;
const depth = bbox.dimensions ? bbox.dimensions[2] : 100;
@@ -232,12 +272,12 @@ class HTMLGenerator:
if (pointcloudData && pointcloudData.points && pointcloudData.points.length > 0) {{
// 创建点云几何体
const pointGeometry = new THREE.BufferGeometry();
const positions = new Float32Array(pointcloudData.points.flat());
const positions = new Float32Array(normalizePositions(pointcloudData.points, centerOffset));
pointGeometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));
// 添加法向量(如果有)
if (pointcloudData.normals && pointcloudData.normals.length > 0) {{
const normals = new Float32Array(pointcloudData.normals.flat());
const normals = new Float32Array(toFlatArray(pointcloudData.normals));
pointGeometry.setAttribute('normal', new THREE.BufferAttribute(normals, 3));
}}
@@ -286,8 +326,8 @@ class HTMLGenerator:
if (cavityVerts.length > 0 && cavityFaces.length > 0) {{
const cavityGeometry = new THREE.BufferGeometry();
const positions = new Float32Array(cavityVerts);
const indices = new Uint32Array(cavityFaces);
const positions = new Float32Array(normalizePositions(cavityVerts, centerOffset));
const indices = new Uint32Array(toFlatArray(cavityFaces));
cavityGeometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));
cavityGeometry.setIndex(new THREE.BufferAttribute(indices, 1));
cavityGeometry.computeVertexNormals();
@@ -331,8 +371,8 @@ class HTMLGenerator:
if (coreVerts.length > 0 && coreFaces.length > 0) {{
const coreGeometry = new THREE.BufferGeometry();
const positions = new Float32Array(coreVerts);
const indices = new Uint32Array(coreFaces);
const positions = new Float32Array(normalizePositions(coreVerts, centerOffset));
const indices = new Uint32Array(toFlatArray(coreFaces));
coreGeometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));
coreGeometry.setIndex(new THREE.BufferAttribute(indices, 1));
coreGeometry.computeVertexNormals();
@@ -364,7 +404,7 @@ class HTMLGenerator:
}}
// 创建分型面(红色平面)
const partingGeometry = new THREE.PlaneGeometry(width * 1.2, depth * 1.2);
const partingGeometry = new THREE.PlaneGeometry(width * 1.2, height * 1.2);
const partingMaterial = new THREE.MeshBasicMaterial({{
color: 0xF44336,
transparent: true,
@@ -373,7 +413,6 @@ class HTMLGenerator:
}});
partingMesh = new THREE.Mesh(partingGeometry, partingMaterial);
partingMesh.rotation.x = Math.PI / 2;
partingMesh.position.set(0, 0, 0);
scene.add(partingMesh);
@@ -392,8 +431,8 @@ class HTMLGenerator:
// 创建简化型腔/A板(定模,分型面以上)— 备用
function createSimpleCavity(width, height, depth) {{
// A板:分型面(Z中心)以上的上半模
const halfHeight = height / 2;
const cavityGeometry = new THREE.BoxGeometry(width * 1.2, depth * 1.2, halfHeight + 10);
const halfDepth = depth / 2;
const cavityGeometry = new THREE.BoxGeometry(width * 1.2, height * 1.2, halfDepth + 10);
const cavityMaterial = new THREE.MeshPhongMaterial({{
color: 0x2196F3,
transparent: true,
@@ -403,7 +442,7 @@ class HTMLGenerator:
cavityMesh = new THREE.Mesh(cavityGeometry, cavityMaterial);
// Z轴开模:A板放在分型面以上
cavityMesh.position.set(0, 0, halfHeight / 2 + 5);
cavityMesh.position.set(0, 0, halfDepth / 2 + 5);
scene.add(cavityMesh);
const cavityWireframe = new THREE.WireframeGeometry(cavityGeometry);
@@ -418,8 +457,8 @@ class HTMLGenerator:
// 创建简化型芯/B板(动模,分型面以下)— 备用
function createSimpleCore(width, height, depth) {{
// B板:分型面(Z中心)以下的下半模
const halfHeight = height / 2;
const coreGeometry = new THREE.BoxGeometry(width * 1.2, depth * 1.2, halfHeight + 10);
const halfDepth = depth / 2;
const coreGeometry = new THREE.BoxGeometry(width * 1.2, height * 1.2, halfDepth + 10);
const coreMaterial = new THREE.MeshPhongMaterial({{
color: 0xFF9800,
transparent: true,
@@ -429,7 +468,7 @@ class HTMLGenerator:
coreMesh = new THREE.Mesh(coreGeometry, coreMaterial);
// Z轴开模:B板放在分型面以下
coreMesh.position.set(0, 0, -halfHeight / 2 - 5);
coreMesh.position.set(0, 0, -halfDepth / 2 - 5);
scene.add(coreMesh);
const coreWireframe = new THREE.WireframeGeometry(coreGeometry);
@@ -441,9 +480,8 @@ class HTMLGenerator:
coreMesh.add(coreLine);
}}
// 设置相机位置
camera.position.set(200, 200, 200);
camera.lookAt(0, 0, 0);
// 统一按场景包围盒调整相机,避免模型错位/尺度不一致导致观感混乱
fitCameraToScene();
// 动画循环
function animate() {{