Stp2Glb/main.py
2026-03-12 08:51:46 +08:00

268 lines
7.7 KiB
Python
Raw Permalink 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转换工具 - Python包装器
调用STP2GLB.exe的友好命令行接口
"""
import argparse
import os
import sys
import subprocess
import pathlib
from typing import List, Optional, Dict, Any
# 质量预设配置
QUALITY_PRESETS = {
'low': {'linear': 0.5, 'angular': 0.8},
'medium': {'linear': 0.1, 'angular': 0.5}, # 默认值
'high': {'linear': 0.01, 'angular': 0.1},
'ultra': {'linear': 0.001, 'angular': 0.05},
'custom': None # 使用用户指定值
}
def find_stp2glb_executable() -> Optional[str]:
"""查找STP2GLB.exe可执行文件"""
# 1. 检查环境变量
if 'STP2GLB_PATH' in os.environ:
exe_path = os.environ['STP2GLB_PATH']
if os.path.isfile(exe_path):
return exe_path
# 2. 当前目录
current_dir = pathlib.Path.cwd()
exe_candidates = ['STP2GLB.exe', 'STP2GLB']
for exe_name in exe_candidates:
exe_path = current_dir / exe_name
if exe_path.is_file():
return str(exe_path)
# 3. Pixi环境目录
pixi_dirs = [
current_dir / '.pixi' / 'envs' / 'dynamic' / 'Library' / 'bin',
current_dir / '.pixi' / 'envs' / 'dynamic-debug' / 'Library' / 'bin',
current_dir / '.pixi' / 'envs' / 'static' / 'Library' / 'bin',
]
for pixi_dir in pixi_dirs:
for exe_name in exe_candidates:
exe_path = pixi_dir / exe_name
if exe_path.is_file():
return str(exe_path)
# 4. 构建目录
build_dirs = list(current_dir.glob('build/*/'))
for build_dir in build_dirs:
for exe_name in exe_candidates:
exe_path = build_dir / exe_name
if exe_path.is_file():
return str(exe_path)
return None
def validate_input_file(input_path: str) -> bool:
"""验证输入文件"""
if not os.path.isfile(input_path):
print(f"错误: 输入文件不存在: {input_path}")
return False
# 检查文件扩展名
ext = pathlib.Path(input_path).suffix.lower()
if ext not in ['.stp', '.step']:
print(f"错误: 输入文件必须是.stp或.step格式当前: {ext}")
return False
return True
def validate_output_file(output_path: str) -> bool:
"""验证输出文件"""
# 检查文件扩展名
ext = pathlib.Path(output_path).suffix.lower()
if ext != '.glb':
print(f"错误: 输出文件必须是.glb格式当前: {ext}")
return False
# 检查目录是否存在
output_dir = pathlib.Path(output_path).parent
if not output_dir.exists():
print(f"错误: 输出目录不存在: {output_dir}")
return False
# 警告如果文件已存在
if os.path.exists(output_path):
print(f"警告: 输出文件已存在,将被覆盖: {output_path}")
return True
def build_command_args(args: argparse.Namespace, exe_path: str) -> List[str]:
"""构建命令行参数"""
cmd_args = [exe_path]
# 必需参数
cmd_args.extend(['--stp', args.input])
cmd_args.extend(['--glb', args.output])
# 质量预设或自定义偏差值
if args.quality == 'custom':
if args.linear_deflection is not None:
cmd_args.extend(['--lin-defl', str(args.linear_deflection)])
if args.angular_deflection is not None:
cmd_args.extend(['--ang-defl', str(args.angular_deflection)])
else:
preset = QUALITY_PRESETS[args.quality]
cmd_args.extend(['--lin-defl', str(preset['linear'])])
cmd_args.extend(['--ang-defl', str(preset['angular'])])
# 可选标志
if args.debug:
cmd_args.append('--debug')
if args.solid_only:
cmd_args.append('--solid-only')
return cmd_args
def run_conversion(cmd_args: List[str]) -> int:
"""运行转换程序"""
try:
print("开始转换...")
print(f"执行命令: {' '.join(cmd_args)}")
print("-" * 50)
# 运行命令并实时显示输出
process = subprocess.run(
cmd_args,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
text=True,
encoding='utf-8'
)
# 显示输出
if process.stdout:
print(process.stdout)
if process.returncode == 0:
print("-" * 50)
print("转换完成!")
else:
print("-" * 50)
print(f"转换失败,退出码: {process.returncode}")
return process.returncode
except Exception as e:
print(f"执行错误: {e}")
return 1
def main():
"""主函数"""
parser = argparse.ArgumentParser(
description='STP到GLB转换工具 - 默认使用层级转换并保留原始组件名称',
formatter_class=argparse.RawDescriptionHelpFormatter
)
# 位置参数
parser.add_argument('input', help='输入的STP文件路径')
parser.add_argument('output', help='输出的GLB文件路径')
# 可选参数
parser.add_argument(
'--linear-deflection',
type=float,
help='线性偏差 (仅在quality=custom时生效)'
)
parser.add_argument(
'--angular-deflection',
type=float,
help='角度偏差 (仅在quality=custom时生效)'
)
parser.add_argument(
'--quality',
choices=['low', 'medium', 'high', 'ultra', 'custom'],
default='medium',
help='网格质量等级 (默认: medium)'
)
parser.add_argument(
'--debug',
action='store_true',
help='调试模式,提供详细的转换信息'
)
parser.add_argument(
'--solid-only',
action='store_true',
help='仅处理实体几何'
)
parser.add_argument(
'--no-scale',
action='store_true',
help='禁用自动缩放 (预留功能)'
)
parser.add_argument(
'--no-center',
action='store_true',
help='禁用自动居中 (预留功能)'
)
args = parser.parse_args()
# 验证自定义质量参数
if args.quality == 'custom':
if args.linear_deflection is None and args.angular_deflection is None:
print("错误: 使用custom质量等级时必须指定--linear-deflection或--angular-deflection")
return 1
# 验证输入输出文件
if not validate_input_file(args.input):
return 1
if not validate_output_file(args.output):
return 1
# 查找可执行文件
exe_path = find_stp2glb_executable()
if not exe_path:
print("错误: 未找到STP2GLB.exe可执行文件")
print("请确保:")
print("1. 已编译项目 (pixi run build && pixi run install)")
print("2. 或设置环境变量STP2GLB_PATH指向可执行文件")
return 1
print(f"使用可执行文件: {exe_path}")
# 显示质量预设信息
if args.quality != 'custom':
preset = QUALITY_PRESETS[args.quality]
print(f"质量等级: {args.quality}")
print(f"线性偏差: {preset['linear']}, 角度偏差: {preset['angular']}")
else:
print("质量等级: custom")
if args.linear_deflection is not None:
print(f"线性偏差: {args.linear_deflection}")
if args.angular_deflection is not None:
print(f"角度偏差: {args.angular_deflection}")
# 预留功能提示
if args.no_scale:
print("注意: --no-scale 功能暂未实现")
if args.no_center:
print("注意: --no-center 功能暂未实现")
# 构建命令参数
cmd_args = build_command_args(args, exe_path)
# 运行转换
return run_conversion(cmd_args)
if __name__ == '__main__':
sys.exit(main())