From acf0aec44d731b4acd30445a972b659282319b65 Mon Sep 17 00:00:00 2001 From: janbridley Date: Fri, 1 May 2026 13:44:39 -0400 Subject: [PATCH 1/4] support obj for polygons --- coxeter/io.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/coxeter/io.py b/coxeter/io.py index 48a54daf..687ed829 100644 --- a/coxeter/io.py +++ b/coxeter/io.py @@ -45,8 +45,13 @@ def to_obj(shape, filename): content += "\n" - for f in shape.faces: - content += f"f {' '.join([str(v_index + 1) for v_index in f])}\n" + if shape.__getattribute__("faces"): + for f in shape.faces: + content += f"f {' '.join([str(v_index + 1) for v_index in f])}\n" + elif shape.__getattribute__("faces"): + content += f"f {' '.join([str(i + 1) for i in range(shape.num_vertices)])}\n" + else: + raise TypeError(f"Unsupported shape type `{type(shape)}` was provided.") content = content[:-1] From b519074c57e7d0181c7d83c0b8bd4f23526dcc39 Mon Sep 17 00:00:00 2001 From: janbridley Date: Fri, 1 May 2026 13:45:00 -0400 Subject: [PATCH 2/4] support 2d obj --- coxeter/shapes/polygon.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/coxeter/shapes/polygon.py b/coxeter/shapes/polygon.py index f59dc328..ffe80614 100644 --- a/coxeter/shapes/polygon.py +++ b/coxeter/shapes/polygon.py @@ -838,3 +838,22 @@ def to_hoomd(self): self.centroid = old_centroid return hoomd_dict + + def save(self, filename): + """Save the polyhedron object to a file using methods from ``coxeter.io``. + + Args: + filename (str, pathlib.Path, or os.PathLike): + The name or path of the output file, including the extension which must + be one of the following: .obj, .off, .stl, .ply, .vtk, .x3d, or .html + + Raises + ------ + ValueError: If the file type does not match one of the valid outputs. + OSError: If open() encounters a problem. + """ + filetype = Path(filename).suffix.lstrip(".").capitalize() + if filetype == "OBJ": + io.to_obj(self, filename) + else: + raise ValueError("filetype must be one of the following: .obj") From 5e2d0f74a3023b0bc5e825cae437ac7ae5db28de Mon Sep 17 00:00:00 2001 From: janbridley Date: Fri, 1 May 2026 13:45:45 -0400 Subject: [PATCH 3/4] Refactor so file type is inferred --- coxeter/shapes/polyhedron.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/coxeter/shapes/polyhedron.py b/coxeter/shapes/polyhedron.py index 1fdb7b3c..2c9fb8f2 100644 --- a/coxeter/shapes/polyhedron.py +++ b/coxeter/shapes/polyhedron.py @@ -5,6 +5,7 @@ import warnings from functools import cached_property +from pathlib import Path import numpy as np import rowan @@ -1022,22 +1023,20 @@ def to_hoomd(self): self.centroid = old_centroid return hoomd_dict - def save(self, filetype, filename): + def save(self, filename): """Save the polyhedron object to a file using methods from ``coxeter.io``. Args: - filetype (str): - The file format to export polyhedron to. Must be one of the following: - OBJ, OFF, STL, PLY, VTK, X3D, HTML. - filename (str, pathlib.Path, or os.PathLike): - The name or path of the output file, including the extension. + The name or path of the output file, including the extension which must + be one of the following: .obj, .off, .stl, .ply, .vtk, .x3d, or .html Raises ------ - ValueError: If filetype is not one of the required strings. + ValueError: If the file type does not match one of the valid outputs. OSError: If open() encounters a problem. """ + filetype = Path(filename).suffix.lstrip(".").capitalize() if filetype == "OBJ": io.to_obj(self, filename) elif filetype == "OFF": @@ -1054,6 +1053,6 @@ def save(self, filetype, filename): io.to_html(self, filename) else: raise ValueError( - "filetype must be one of the following: OBJ, OFF, " - "STL, PLY, VTK, X3D, HTML" + "filetype must be one of the following: .obj, .off, .stl, .ply, .vtk, " + ".x3d, or .html" ) From 28b2077e8d3b96bfa037dc481c5d627fc1267dce Mon Sep 17 00:00:00 2001 From: janbridley Date: Fri, 1 May 2026 13:47:05 -0400 Subject: [PATCH 4/4] fix 2d case --- coxeter/io.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coxeter/io.py b/coxeter/io.py index 687ed829..6a902c19 100644 --- a/coxeter/io.py +++ b/coxeter/io.py @@ -48,7 +48,7 @@ def to_obj(shape, filename): if shape.__getattribute__("faces"): for f in shape.faces: content += f"f {' '.join([str(v_index + 1) for v_index in f])}\n" - elif shape.__getattribute__("faces"): + elif shape.__getattribute__("num_vertices"): # Pack all vertices into one facet content += f"f {' '.join([str(i + 1) for i in range(shape.num_vertices)])}\n" else: raise TypeError(f"Unsupported shape type `{type(shape)}` was provided.")