feat: initial commit - massive-cloud point cloud processing system
This commit is contained in:
94
scripts/step_parse_mvp.py
Normal file
94
scripts/step_parse_mvp.py
Normal file
@@ -0,0 +1,94 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
STEP → 每 solid 一个 STL + manifest.json(需 cadquery:pip install cadquery)
|
||||
用法: python3 step_parse_mvp.py <step_path> <out_dir>
|
||||
stdout 打印一行 JSON: {"ok":true} 或 {"ok":false,"error":"..."}
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
def main() -> None:
|
||||
if len(sys.argv) < 3:
|
||||
err = {"ok": False, "error": "usage: step_parse_mvp.py <step_path> <out_dir>"}
|
||||
print(json.dumps(err), flush=True)
|
||||
sys.exit(2)
|
||||
|
||||
step_path = sys.argv[1]
|
||||
out_dir = sys.argv[2]
|
||||
|
||||
try:
|
||||
import cadquery as cq # type: ignore
|
||||
except ImportError as e:
|
||||
# pip3 与 python3 可能不是同一解释器,须用「当前解释器」安装:见 sys.executable
|
||||
exe = sys.executable
|
||||
pip_cmd = (
|
||||
f'"{exe}" -m pip install --break-system-packages '
|
||||
f"-i https://pypi.tuna.tsinghua.edu.cn/simple cadquery"
|
||||
)
|
||||
detail = f"{type(e).__name__}: {e}"
|
||||
err = {
|
||||
"ok": False,
|
||||
"error": (
|
||||
f"无法 import cadquery({detail})。当前 Python: {exe}。"
|
||||
f"请用**同一解释器**安装(勿单独用 pip3,除非确认与 python3 一致): {pip_cmd}"
|
||||
),
|
||||
}
|
||||
print(json.dumps(err, ensure_ascii=False), flush=True)
|
||||
sys.exit(1)
|
||||
|
||||
if not os.path.isfile(step_path):
|
||||
err = {"ok": False, "error": f"文件不存在: {step_path}"}
|
||||
print(json.dumps(err), flush=True)
|
||||
sys.exit(1)
|
||||
|
||||
os.makedirs(out_dir, exist_ok=True)
|
||||
|
||||
try:
|
||||
wp = cq.importers.importStep(step_path)
|
||||
except Exception as e:
|
||||
err = {"ok": False, "error": f"importStep: {e}"}
|
||||
print(json.dumps(err), flush=True)
|
||||
sys.exit(1)
|
||||
|
||||
solids: list = []
|
||||
try:
|
||||
solids = list(wp.solids().vals())
|
||||
except Exception:
|
||||
try:
|
||||
solids = [wp.val()]
|
||||
except Exception as e:
|
||||
err = {"ok": False, "error": f"无法取得实体: {e}"}
|
||||
print(json.dumps(err), flush=True)
|
||||
sys.exit(1)
|
||||
|
||||
if not solids:
|
||||
err = {"ok": False, "error": "STEP 中未解析出任何 Solid"}
|
||||
print(json.dumps(err), flush=True)
|
||||
sys.exit(1)
|
||||
|
||||
parts: list[dict] = []
|
||||
for i, solid in enumerate(solids):
|
||||
name = f"part_{i:04d}"
|
||||
stl_name = f"{name}.stl"
|
||||
stl_path = os.path.join(out_dir, stl_name)
|
||||
cq.exporters.export(solid, stl_path)
|
||||
parts.append({"id": name, "name": name, "stlRelative": stl_name})
|
||||
|
||||
manifest = {"ok": True, "parts": parts, "sourceStep": os.path.abspath(step_path)}
|
||||
man_path = os.path.join(out_dir, "manifest.json")
|
||||
with open(man_path, "w", encoding="utf-8") as f:
|
||||
json.dump(manifest, f, indent=2, ensure_ascii=False)
|
||||
|
||||
result_line = json.dumps({"ok": True, "parts": parts, "manifestPath": man_path})
|
||||
# Node 端若 stdout 含 OCP 杂讯,仍可从该文件读取结果
|
||||
with open(os.path.join(out_dir, "_parse_result.json"), "w", encoding="utf-8") as f:
|
||||
f.write(result_line)
|
||||
print(result_line, flush=True)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user