diff --git a/include/csg_types.hpp b/include/csg_types.hpp index 7004c81adb02d94f58a12b4d86df8312648c01cd..290579417e3e5b2cc956cb91d6522ec7f7e66803 100644 --- a/include/csg_types.hpp +++ b/include/csg_types.hpp @@ -58,12 +58,9 @@ private: public: std::optional name; - Polyhedron(const std::vector> &points, - const std::vector> &faces) { - for (const auto &pt : points) { - assert(pt.size() == 3); - m_points.push_back({pt[0], pt[1], pt[2]}); - } + Polyhedron(const std::vector> &points, + const std::vector> &faces) + : m_points(points) { for (const auto &f : faces) { m_faces.push_back(std::vector(f.begin(), f.end())); } @@ -83,12 +80,9 @@ private: public: std::optional name; - Polygon(const std::vector> &points, - const std::vector &path) { - for (const auto &pt : points) { - assert(pt.size() == 2); - m_points.push_back({pt[0], pt[1]}); - } + Polygon(const std::vector> &points, + const std::vector &path) + : m_points(points) { for (const auto &p : path) { m_path.push_back((unsigned int)(p)); } diff --git a/src/csg/CMakeLists.txt b/src/csg/CMakeLists.txt index f3d2aba7b515a8e2b5c41439208a873e201c0885..669bca38414e73863727fc5d04ec1e8d9760a0bd 100644 --- a/src/csg/CMakeLists.txt +++ b/src/csg/CMakeLists.txt @@ -9,6 +9,7 @@ add_library(csg levelset_3d.cpp matrix_functions.cpp parser.cpp + exception.cpp ) target_link_libraries(csg PRIVATE diff --git a/src/csg/cgal_helper_polyhedron.cpp b/src/csg/cgal_helper_polyhedron.cpp index ad43e7f77aed26c1ea0633cecca8dca7a074684f..2cc5bf99c6fd2df8140020d50ef39b49b517d7f5 100644 --- a/src/csg/cgal_helper_polyhedron.cpp +++ b/src/csg/cgal_helper_polyhedron.cpp @@ -1,4 +1,5 @@ #include "csg_cgal_helper.hpp" +#include "csg_exception.hpp" #include #include @@ -46,6 +47,11 @@ public: // Add facets next for (const auto &face : m_faces) { B.begin_facet(); + if (!B.test_facet(face.begin(), face.end())) + throw csg::Exception( + "Polyhedron builder", + "Unable to create the polyhedron. test_facet failed. Check input!"); + for (const auto &p_index : face) { B.add_vertex_to_facet(p_index); } diff --git a/src/csg/exception.cpp b/src/csg/exception.cpp new file mode 100644 index 0000000000000000000000000000000000000000..33cde0058d36c194af6823ec285a5fe589ce5284 --- /dev/null +++ b/src/csg/exception.cpp @@ -0,0 +1,27 @@ +#include "csg_exception.hpp" + +#include +#include + +namespace csg { + +Exception::Exception() : m_msg(make_message("No Source", "No message")) {} + +Exception::Exception(const std::string &message) + : m_msg(make_message("No Source", message)) {} + +Exception::Exception(const std::string &source, const std::string &message) + : m_msg(make_message(source, message)) {} + +const char *Exception::what() const noexcept { return m_msg.c_str(); } + +std::string Exception::make_message(const std::string &source, + const std::string &message) { + std::stringstream s; + s << "Exception Data:" << std::endl; + s << "Source : " << source << std::endl; + s << "Message : " << message << std::endl; + return s.str(); +} + +} // namespace csg diff --git a/src/csg/meson.build b/src/csg/meson.build index 6d81be45ac26f561fde90354387ef50413487dbd..d3461767718bf03f955a4c4280740ae96e75b52a 100644 --- a/src/csg/meson.build +++ b/src/csg/meson.build @@ -6,6 +6,7 @@ lib_csg_parser = static_library('csg-parser', 'levelset_3d.cpp', 'matrix_functions.cpp', 'parser.cpp', + 'exception.cpp', include_directories: parser_inc, dependencies: [pegtl, cgal], install : true) diff --git a/src/csg/parser.cpp b/src/csg/parser.cpp index 7e8491e5e74c531730c7c9086e43586853ab68b6..fc57aaba18ac780bb086adbb203da5a532ae5342 100644 --- a/src/csg/parser.cpp +++ b/src/csg/parser.cpp @@ -1,12 +1,13 @@ // standard includes -#include #include #include +#include // subproject includes #include // includes +#include "csg_exception.hpp" #include "csg_types.hpp" using namespace tao::pegtl; @@ -509,9 +510,9 @@ template <> struct action { if (curr_attr.count("r")) { // proper cylinder if (curr_attr.count("r1") || curr_attr.count("r2")) { - std::cout << " ERROR: cannot specify both r and (r1 or r2); ambiguous " - << std::endl; - assert(false); + throw csg::Exception( + "action", + " ERROR: cannot specify both r and (r1 or r2); ambiguous "); } csg::Cylinder cyl; cyl.name = get_name(curr_attr); @@ -585,12 +586,22 @@ template <> struct action { std::stringstream ss(in.string()); auto &curr_attr = st.curr_attrs.back(); - auto points = + auto points_raw = std::get>>(curr_attr["points"]); + std::vector> points; + for (const auto &pt : points_raw) { + if (pt.size() != 2) + throw csg::Exception("action", "pt.size() != 2"); + points.push_back({pt[0], pt[1]}); + } + std::vector> paths = {{}}; if (std::holds_alternative(curr_attr["paths"])) { - assert(std::get(curr_attr["paths"]) == UNDEFINED_STR); + auto paths_str = std::get(curr_attr["paths"]); + if (paths_str != UNDEFINED_STR) + throw csg::Exception("action", + "paths = " + paths_str + " not recognized"); } else { paths = std::get>>(curr_attr["paths"]); } @@ -616,10 +627,17 @@ template <> struct action { std::stringstream ss(in.string()); auto &curr_attr = st.curr_attrs.back(); - auto points = + auto points_raw = std::get>>(curr_attr["points"]); auto faces = std::get>>(curr_attr["faces"]); + std::vector> points; + for (const auto &pt : points_raw) { + if (pt.size() != 3) + throw csg::Exception("action", "pt.size() != 3"); + points.push_back({pt[0], pt[1], pt[2]}); + } + csg::Polyhedron polyh(points, faces); polyh.name = get_name(curr_attr); @@ -728,11 +746,16 @@ std::shared_ptr parse_csg(std::string str) { auto st = maybe_state.value(); assert(st.current_3d_objs.size() == 1); + Tree tree; for (auto obj : st.current_3d_objs.back()) { tree.top.objs.push_back(obj); } - assert(tree.top.objs.size() > 0); // Disallow empty .csg file + + if (tree.top.objs.empty()) + throw csg::Exception("parse_csg", + "Empty csg file"); // Disallow empty .csg file + return std::make_shared(tree); } } // namespace csg diff --git a/src/csg_exception.hpp b/src/csg_exception.hpp new file mode 100644 index 0000000000000000000000000000000000000000..2e7858a1802948922a5813e06d6d2d99c67ff545 --- /dev/null +++ b/src/csg_exception.hpp @@ -0,0 +1,24 @@ +#ifndef CSG_EXCEPTION_H_ +#define CSG_EXCEPTION_H + +#include +#include + +namespace csg { + +class Exception : public std::exception { +public: + Exception(); + explicit Exception(const std::string &message); + Exception(const std::string &source, const std::string &message); + const char *what() const noexcept; + +private: + std::string make_message(const std::string &source, + const std::string &message); + std::string m_msg; +}; + +} // namespace csg + +#endif