File size: 3,593 Bytes
6e2cb7f 676f248 6e2cb7f 676f248 44b4dd3 6e2cb7f 61287af 6e2cb7f 676f248 6e2cb7f 61287af 6e2cb7f 676f248 44b4dd3 6e2cb7f 676f248 44b4dd3 6e2cb7f 44b4dd3 6e2cb7f 676f248 44b4dd3 6e2cb7f | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | from __future__ import annotations
import argparse
import json
import traceback
from pathlib import Path
import runtime_env # noqa: F401
import numpy as np
import torch
from glb_export import export_glb as _export_glb
def _deserialize_attr_layout(payload: dict[str, dict[str, int]]) -> dict[str, slice]:
return {key: slice(value["start"], value["stop"]) for key, value in payload.items()}
def export_glb(
*,
payload_npz: Path,
payload_meta: Path,
output_path: Path,
decimation_target: int,
texture_size: int,
remesh: bool = True,
safe_nonremesh_fallback: bool | None = None,
) -> None:
arrays = np.load(payload_npz)
meta = json.loads(payload_meta.read_text(encoding="utf-8"))
attr_layout = _deserialize_attr_layout(meta["attr_layout"])
resolution = int(meta["resolution"])
aabb = meta["aabb"]
vertices = torch.from_numpy(arrays["vertices"]).cuda()
faces = torch.from_numpy(arrays["faces"]).cuda()
attr_volume = torch.from_numpy(arrays["attrs"]).cuda()
coords = torch.from_numpy(arrays["coords"]).cuda()
torch.cuda.synchronize()
glb = _export_glb(
vertices=vertices,
faces=faces,
attr_volume=attr_volume,
coords=coords,
attr_layout=attr_layout,
grid_size=resolution,
aabb=aabb,
decimation_target=decimation_target,
texture_size=texture_size,
remesh=remesh,
safe_nonremesh_fallback=safe_nonremesh_fallback,
use_tqdm=False,
)
torch.cuda.synchronize()
glb.export(str(output_path), extension_webp=True)
def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument("--payload-npz", required=True)
parser.add_argument("--payload-meta", required=True)
parser.add_argument("--output", required=True)
parser.add_argument("--decimation-target", type=int, required=True)
parser.add_argument("--texture-size", type=int, required=True)
parser.add_argument(
"--remesh", type=int, default=1, help="1 = remesh (default), 0 = no remesh"
)
parser.add_argument(
"--safe-nonremesh-fallback",
type=int,
default=-1,
help="1 = safe fallback, 0 = upstream raw, -1 = use env var (default)",
)
parser.add_argument("--result-json", required=True)
args = parser.parse_args()
safe_val: bool | None = None
if args.safe_nonremesh_fallback >= 0:
safe_val = bool(args.safe_nonremesh_fallback)
result_path = Path(args.result_json)
try:
export_glb(
payload_npz=Path(args.payload_npz),
payload_meta=Path(args.payload_meta),
output_path=Path(args.output),
decimation_target=args.decimation_target,
texture_size=args.texture_size,
remesh=bool(args.remesh),
safe_nonremesh_fallback=safe_val,
)
result_path.write_text(
json.dumps(
{"ok": True, "output_path": args.output}, indent=2, sort_keys=True
),
encoding="utf-8",
)
return 0
except Exception as error:
result_path.write_text(
json.dumps(
{
"ok": False,
"error_type": type(error).__name__,
"message": str(error),
"traceback": traceback.format_exc(),
},
indent=2,
sort_keys=True,
),
encoding="utf-8",
)
return 1
if __name__ == "__main__":
raise SystemExit(main())
|