diff --git a/include/gdstk/utils.hpp b/include/gdstk/utils.hpp index 35ec2729..a487775d 100644 --- a/include/gdstk/utils.hpp +++ b/include/gdstk/utils.hpp @@ -69,6 +69,7 @@ enum struct ErrorCode { NoError = 0, // Warnings BooleanError, + EmptyPath, IntersectionNotFound, MissingReference, UnsupportedRecord, diff --git a/python/gdstk_module.cpp b/python/gdstk_module.cpp index 850cb9cb..212baf94 100644 --- a/python/gdstk_module.cpp +++ b/python/gdstk_module.cpp @@ -51,6 +51,9 @@ static int return_error(ErrorCode error_code) { case ErrorCode::NoError: return 0; // Warnings + case ErrorCode::EmptyPath: + if (PyErr_WarnEx(PyExc_RuntimeWarning, "Empty path.", 1) != 0) return -1; + return 0; case ErrorCode::MissingReference: if (PyErr_WarnEx(PyExc_RuntimeWarning, "Missing reference.", 1) != 0) return -1; return 0; diff --git a/src/flexpath.cpp b/src/flexpath.cpp index 4693eb61..071e4125 100644 --- a/src/flexpath.cpp +++ b/src/flexpath.cpp @@ -239,7 +239,7 @@ void FlexPath::remove_overlapping_points() { ErrorCode FlexPath::to_polygons(bool filter, Tag tag, Array& result) { remove_overlapping_points(); - if (spine.point_array.count < 2) return ErrorCode::NoError; + if (spine.point_array.count < 2) return ErrorCode::EmptyPath; const Array spine_points = spine.point_array; uint64_t curve_size_guess = spine_points.count * 2 + 4; @@ -774,7 +774,7 @@ ErrorCode FlexPath::to_gds(FILE* out, double scaling) { remove_overlapping_points(); - if (spine.point_array.count < 2) return error_code; + if (spine.point_array.count < 2) return ErrorCode::EmptyPath; uint16_t buffer_end[] = {4, 0x1100}; big_endian_swap16(buffer_end, COUNT(buffer_end)); @@ -918,7 +918,7 @@ ErrorCode FlexPath::to_oas(OasisStream& out, OasisState& state) { remove_overlapping_points(); - if (spine.point_array.count < 2) return error_code; + if (spine.point_array.count < 2) return ErrorCode::EmptyPath; bool has_repetition = repetition.get_count() > 1; diff --git a/tests/library_test.py b/tests/library_test.py index 2f9ba863..e6d29e32 100644 --- a/tests/library_test.py +++ b/tests/library_test.py @@ -561,3 +561,35 @@ def test_write_min_length_path( source.cells[0].paths[0].spine(), rw.cells[0].paths[0].spine(), ) + + +@pytest.mark.parametrize( + "simple_path", (True, False), +) +@pytest.mark.parametrize( + "write_f", + (gdstk.Library.write_oas, gdstk.Library.write_gds), +) +def test_empty_path_warning( + simple_path: bool, + write_f: Callable[[gdstk.Library, Union[str, pathlib.Path]], None], + tmp_path: pathlib.Path +): + lib = gdstk.Library("test") + tol = lib.precision / lib.unit + + # Simple paths are written to GDS & OASIS with PATH records; non-simple + # paths are serialized as polygons. + path = gdstk.FlexPath( + ((0, 0), (tol / 2, 0)), + width=0.01, + tolerance=tol, + simple_path=simple_path + ) + + cell = gdstk.Cell("top") + cell.add(path) + lib.add(cell) + + with pytest.warns(RuntimeWarning, match="Empty path"): + write_f(lib, tmp_path / "out")