"""Open3D's boxes on the source meshes' vertices: the principal-axes OBB (get_oriented_bounding_box) and the minimal
OBB (get_minimal_oriented_bounding_box), against trimesh's minimum-volume OBB; out/bounds_o3d.csv.

    env -u PYTHONPATH ~/code/data/meshes/fcp_2910_collision/.venv/bin/python scripts/bounds_o3d.py
"""
import sys
import time
from pathlib import Path

import numpy as np
import open3d as o3d
import trimesh

sys.argv = [sys.argv[0], "x"]
sys.path.insert(0, str(Path(__file__).parent))
from hull import OBJECTS, OUT  # noqa: E402


def med(f, n=21):
    f()
    t = []
    for _ in range(n):
        t0 = time.perf_counter()
        f()
        t.append(time.perf_counter() - t0)
    return 1e3 * float(np.median(t))


rows = []
for name, path in OBJECTS.items():
    m = trimesh.load(path, force="mesh")
    pts = o3d.utility.Vector3dVector(np.asarray(m.vertices, float))
    ref = float(np.prod(trimesh.bounds.oriented_bounds(m)[1]))
    pca = o3d.geometry.OrientedBoundingBox.create_from_points(pts)
    mini = o3d.geometry.OrientedBoundingBox.create_from_points_minimal(pts)
    aabb = o3d.geometry.AxisAlignedBoundingBox.create_from_points(pts)
    rows.append(dict(obj=name, o3d_pca_ms=med(lambda: o3d.geometry.OrientedBoundingBox.create_from_points(pts)),
                     o3d_pca_vol_ratio=pca.volume() / ref,
                     o3d_min_ms=med(lambda: o3d.geometry.OrientedBoundingBox.create_from_points_minimal(pts), 7),
                     o3d_min_vol_ratio=mini.volume() / ref,
                     o3d_aabb_ms=med(lambda: o3d.geometry.AxisAlignedBoundingBox.create_from_points(pts))))
    print(rows[-1], flush=True)
import pandas as pd  # noqa: E402

pd.DataFrame(rows).to_csv(OUT / "bounds_o3d.csv", index=False)
