Repository navigation
Expand file tree
/
Copy pathtest_obj.py
More file actions
63 lines (45 loc) · 1.53 KB
/
Copy pathtest_obj.py
File metadata and controls
63 lines (45 loc) · 1.53 KB
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
from __future__ import annotations
import argparse
from pathlib import Path
import trimesh
import xatlas
def unwrap_obj(input_path: Path, output_path: Path) -> None:
loaded = trimesh.load(input_path, force="mesh", process=False)
if not isinstance(loaded, trimesh.Trimesh):
raise TypeError(f"Expected one mesh, received {type(loaded).__name__}")
if len(loaded.vertices) == 0 or len(loaded.faces) == 0:
raise ValueError("The OBJ contains no usable triangle mesh.")
vmapping, indices, uvs = xatlas.parametrize(
loaded.vertices,
loaded.faces,
)
output_path.parent.mkdir(parents=True, exist_ok=True)
xatlas.export(
str(output_path),
loaded.vertices[vmapping],
indices,
uvs,
)
print(f"Input: {input_path.resolve()}")
print(f"Output: {output_path.resolve()}")
print(f"Atlas vertices: {len(vmapping)}")
print(f"Atlas triangles: {len(indices)}")
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(description="Basic xatlas OBJ test")
parser.add_argument("input", type=Path, help="Input OBJ path")
parser.add_argument(
"-o",
"--output",
type=Path,
default=Path("unwrapped.obj"),
help="Output OBJ path",
)
return parser.parse_args()
def main() -> int:
args = parse_args()
if not args.input.is_file():
raise FileNotFoundError(args.input)
unwrap_obj(args.input, args.output)
return 0
if __name__ == "__main__":
raise SystemExit(main())