feat: 算法升级、整车配准集成与性能分析文档

算法更新: delivery v1.2.1、平整度v1.5、测距v2.2、整车配准v1.3
适配器: vehicle-registration 新增、各算法 manifest 和 adapter 更新
后端: taskCadFiles/source 字段迁移、derivedPointClouds 注册、取消任务联动
前端: ElapsedTime 时长显示、两步算法流程、canRun 逻辑修复
文档: 新增5份算法性能分析报告
This commit is contained in:
2026-06-25 08:22:20 +00:00
parent cec0766e67
commit 29f1d45d66
266 changed files with 1311475 additions and 2846 deletions

View File

@@ -0,0 +1,118 @@
from __future__ import annotations
import time
from pathlib import Path
import numpy as np
class CADConverter:
"""Convert STEP CAD files to STL meshes."""
def read_step_shape(self, input_step: str | Path):
try:
from OCC.Core.IFSelect import IFSelect_RetDone
from OCC.Core.STEPControl import STEPControl_Reader
except ModuleNotFoundError as exc:
raise RuntimeError(
"pythonocc-core is required for CAD conversion. "
"Install it with conda-forge before running CAD workflows."
) from exc
input_step = Path(input_step)
step_reader = STEPControl_Reader()
if step_reader.ReadFile(str(input_step)) != IFSelect_RetDone:
raise ValueError(f"Failed to read STEP file: {input_step}")
step_reader.TransferRoots()
return step_reader.OneShape()
def step_to_numpy_mesh(
self,
input_step: str | Path,
mesh_deflection: float = 0.1,
) -> tuple[np.ndarray, np.ndarray]:
try:
from OCC.Core.BRep import BRep_Tool
from OCC.Core.BRepMesh import BRepMesh_IncrementalMesh
from OCC.Core.TopAbs import TopAbs_FACE
from OCC.Core.TopExp import TopExp_Explorer
try:
from OCC.Core.TopoDS import topods
except ImportError:
from OCC.Core.TopoDS import TopoDS
topods = None
except ModuleNotFoundError as exc:
raise RuntimeError(
"pythonocc-core is required for CAD mesh extraction. "
"Install it with conda-forge before running CAD workflows."
) from exc
shape = self.read_step_shape(input_step)
mesh = BRepMesh_IncrementalMesh(shape, mesh_deflection, False)
mesh.Perform()
if not mesh.IsDone():
raise RuntimeError("CAD mesh discretization failed.")
vertices: list[list[float]] = []
faces: list[list[int]] = []
explorer = TopExp_Explorer(shape, TopAbs_FACE)
while explorer.More():
current_shape = explorer.Current()
face = topods.Face(current_shape) if topods is not None else TopoDS.Face(current_shape)
location = face.Location()
triangulation = BRep_Tool.Triangulation(face, location)
if triangulation is None:
explorer.Next()
continue
transform = location.Transformation()
base_index = len(vertices)
for index in range(1, triangulation.NbNodes() + 1):
point = triangulation.Node(index)
point.Transform(transform)
vertices.append([point.X(), point.Y(), point.Z()])
for index in range(1, triangulation.NbTriangles() + 1):
n1, n2, n3 = triangulation.Triangle(index).Get()
faces.append([base_index + n1 - 1, base_index + n2 - 1, base_index + n3 - 1])
explorer.Next()
vertices_np = np.asarray(vertices, dtype=np.float64)
faces_np = np.asarray(faces, dtype=np.int64)
if len(vertices_np) == 0 or len(faces_np) == 0:
raise RuntimeError("CAD triangle mesh extraction failed; try a smaller mesh deflection.")
return vertices_np, faces_np
def convert_step_to_stl(self, input_step: str | Path, output_stl: str | Path, precision: float = 1.0) -> Path:
try:
from OCC.Core.BRepMesh import BRepMesh_IncrementalMesh
from OCC.Core.StlAPI import StlAPI_Writer
except ModuleNotFoundError as exc:
raise RuntimeError(
"pythonocc-core is required for CAD conversion. "
"Install it with conda-forge before running cad2mesh."
) from exc
input_step = Path(input_step)
output_stl = Path(output_stl)
output_stl.parent.mkdir(parents=True, exist_ok=True)
start = time.time()
print(f"[1/3] Reading STEP: {input_step}")
shape = self.read_step_shape(input_step)
print(f"[2/3] Meshing with precision {precision} mm")
mesh = BRepMesh_IncrementalMesh(shape, precision, False)
mesh.Perform()
if not mesh.IsDone():
raise RuntimeError("Mesh discretization failed.")
print(f"[3/3] Writing STL: {output_stl}")
writer = StlAPI_Writer()
writer.Write(shape, str(output_stl))
print(f"CAD conversion finished in {time.time() - start:.2f}s")
return output_stl