-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* save obj files, run end-to-end test * don't run e2e test by default
- Loading branch information
1 parent
b9c09d5
commit 771e323
Showing
6 changed files
with
143 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
"""Defines utility functions for operations on meshes.""" | ||
|
||
from pathlib import Path | ||
from typing import Literal, cast | ||
|
||
import stl.mesh | ||
|
||
MeshExt = Literal["stl", "obj"] | ||
|
||
|
||
def stl_to_obj(stl_path: str | Path, obj_path: str | Path) -> None: | ||
"""Converts an STL file to an OBJ file. | ||
Args: | ||
stl_path: The path to the STL file. | ||
obj_path: The path to the OBJ file. | ||
""" | ||
mesh = stl.mesh.Mesh.from_file(stl_path) | ||
|
||
vertices: dict[tuple[float, float, float], int] = {} | ||
faces: list[tuple[int, int, int]] = [] | ||
index = 1 | ||
|
||
# Process each triangle in the mesh | ||
for i in range(len(mesh.vectors)): | ||
face = [] | ||
for point in mesh.vectors[i]: | ||
vertex = cast(tuple[float, float, float], tuple(point)) | ||
if vertex not in vertices: | ||
vertices[vertex] = index | ||
index += 1 | ||
face.append(vertices[vertex]) | ||
face_tuple = cast(tuple[int, int, int], tuple(face)) | ||
faces.append(face_tuple) | ||
|
||
with open(obj_path, "w") as f: | ||
for vertex, _ in sorted(vertices.items(), key=lambda x: x[1]): | ||
f.write(f"v {' '.join(map(str, vertex))}\n") | ||
for face_tuple in faces: | ||
f.write(f"f {' '.join(map(str, face_tuple))}\n") | ||
|
||
|
||
def stl_to_fmt(stl_path: str | Path, output_path: str | Path) -> None: | ||
stl_path = Path(stl_path) | ||
ext = Path(output_path).suffix[1:] | ||
|
||
match ext: | ||
case "stl": | ||
return | ||
|
||
case "obj": | ||
stl_to_obj(stl_path, output_path) | ||
|
||
case _: | ||
raise ValueError(f"Unsupported mesh format: {ext}") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
"""Runs an end-to-end test of the URDF exporter on the Stompy model.""" | ||
|
||
from pathlib import Path | ||
from typing import get_args | ||
|
||
import pytest | ||
|
||
from kol import urdf | ||
from kol.logging import configure_logging | ||
from kol.mesh import MeshExt | ||
from kol.onshape.converter import Converter | ||
|
||
STOMPY_ONSHAPE_URL = ( | ||
"https://cad.onshape.com/documents/71f793a23ab7562fb9dec82d/w/" | ||
"6160a4f44eb6113d3fa116cd/e/1a95e260677a2d2d5a3b1eb3" | ||
) | ||
|
||
|
||
@pytest.mark.skip(reason="This test is slow and requires an internet connection") | ||
def test_e2e(tmpdir: Path) -> None: | ||
"""Runs an end-to-end test of the URDF exporter on the Stompy model. | ||
Args: | ||
tmpdir: The temporary directory to save the URDF file. | ||
ext: The mesh file format. | ||
""" | ||
for mesh_ext in get_args(MeshExt): | ||
Converter( | ||
document_url=STOMPY_ONSHAPE_URL, | ||
output_dir=tmpdir, | ||
default_prismatic_joint_limits=urdf.JointLimits(10, 10, -10, 10), | ||
default_revolute_joint_limits=urdf.JointLimits(10, 10, -10, 10), | ||
suffix_to_joint_effort=[ | ||
("dof_x4_h", 1.5), | ||
("dof_x4", 1.5), | ||
("dof_x6", 3), | ||
("dof_x8", 6), | ||
("dof_x10", 12), | ||
("knee_revolute", 13.9), | ||
("ankle_revolute", 6), | ||
], | ||
suffix_to_joint_velocity=[], | ||
disable_mimics=True, | ||
mesh_ext=mesh_ext, | ||
).save_urdf() | ||
|
||
|
||
if __name__ == "__main__": | ||
# python -m tests.test_e2e | ||
configure_logging() | ||
test_e2e(Path.cwd() / "test_e2e") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
"""Tests mesh conversion options.""" | ||
|
||
from pathlib import Path | ||
|
||
from kol.mesh import stl_to_fmt | ||
|
||
|
||
def test_stl_to_obj(tmpdir: Path) -> None: | ||
obj_path = Path(tmpdir / "random.obj") | ||
stl_to_fmt("tests/data/random.stl", obj_path) | ||
assert obj_path.exists() |