TellmeStpToGlb/core/converter.py
sladro 90ba65e484 feat: 实现基于XCAF的真正装配结构保留转换
- 新增XCAF转换器,直接从STP到GLB保留完整装配层级
- 修复HTTP API与CLI参数不一致问题
- 修复静默吞没错误的问题,遵循快速失败原则
- 清理旧文件,整理测试文件到tests目录
- 添加URL下载支持,可直接转换远程STP文件
- 更新文档,准确描述XCAF装配保留功能

技术改进:
- 使用STEPCAFControl_Reader读取带装配信息的STEP文件
- 通过RWGltf_CafWriter直接导出GLB,无需STL中间格式
- 支持CPU多线程并行三角化
- HTTP API和CLI使用完全一致的转换参数

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-09 16:50:48 +08:00

121 lines
4.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
"""
STP到GLB转换器类
使用XCAF直接保留装配结构无需STL中间步骤
"""
import os
from typing import Callable, Optional, List, Dict, Literal
from utils.network_helper import is_url, download_file, cleanup_downloaded_file
# 导入XCAF转换器
try:
from .converter_xcaf import XCAFConverter, check_xcaf_availability
XCAF_AVAILABLE = True
except ImportError:
XCAF_AVAILABLE = False
XCAFConverter = None
class StpToGlbConverter:
"""STP到GLB转换器"""
def __init__(self):
"""初始化转换器使用XCAF管线"""
self.progress_callback: Optional[Callable[[int, str], None]] = None
self.downloaded_file_path: Optional[str] = None # 记录下载的临时文件路径
# 检查XCAF可用性
if not XCAF_AVAILABLE:
raise RuntimeError("XCAF模块不可用请检查pythonocc安装")
self.xcaf_converter = XCAFConverter()
if not self.xcaf_converter.is_available():
status = self.xcaf_converter.get_availability_status()
raise RuntimeError(f"XCAF转换器不可用: {status['message']}")
def set_progress_callback(self, callback: Callable[[int, str], None]) -> None:
"""设置进度回调函数"""
self.progress_callback = callback
if self.xcaf_converter:
self.xcaf_converter.set_progress_callback(callback)
def _update_progress(self, progress: int, message: str) -> None:
"""更新进度"""
if self.progress_callback:
self.progress_callback(progress, message)
def _prepare_input_file(self, stp_path: str) -> str:
"""
准备输入文件下载URL或验证本地文件
Args:
stp_path: STP文件路径或URL
Returns:
str: 本地文件路径
"""
if is_url(stp_path):
self._update_progress(1, f"检测到URL输入: {stp_path}")
# 下载文件到临时位置
self.downloaded_file_path = download_file(stp_path, self.progress_callback)
self._update_progress(95, f"文件下载完成: {self.downloaded_file_path}")
return self.downloaded_file_path
else:
# 本地文件验证
self._update_progress(5, "检查本地输入文件...")
if not os.path.isfile(stp_path):
raise FileNotFoundError(f"找不到文件:{stp_path}")
return stp_path
def _cleanup_downloaded_file(self) -> None:
"""清理下载的临时文件"""
if self.downloaded_file_path:
cleanup_downloaded_file(self.downloaded_file_path)
self.downloaded_file_path = None
def convert(self, stp_path: str, glb_path: str,
linear_deflection: float = 0.01, angular_deflection: float = 0.1,
embed_textures: bool = True, y_up: bool = True, **kwargs) -> None:
"""
STP到GLB转换直接保留装配结构
Args:
stp_path: 输入STEP文件路径或URL支持HTTP/HTTPS
glb_path: 输出GLB文件路径
linear_deflection: 线性偏差(控制网格精度)
angular_deflection: 角度偏差(控制网格精度)
embed_textures: 是否嵌入纹理
y_up: 是否使用Y向上坐标系
**kwargs: 忽略的其他参数(用于兼容性)
"""
try:
# 准备输入文件(可能需要下载)
local_stp_path = self._prepare_input_file(stp_path)
# 使用XCAF转换保留装配结构
self.xcaf_converter.convert_with_xcaf(
local_stp_path, glb_path,
embed_textures=embed_textures,
y_up=y_up,
linear_deflection=linear_deflection,
angular_deflection=angular_deflection
)
finally:
# 清理下载的文件
self._cleanup_downloaded_file()
def get_info(self) -> dict:
"""获取转换器信息"""
status = self.xcaf_converter.get_availability_status() if self.xcaf_converter else {}
return {
"converter": "XCAF",
"capabilities": {
"assembly_hierarchy": True,
"component_names": True,
"colors": True,
"materials": True,
"instances": True
},
"status": status
}