From 4d6cba1a1d74c9ebd83aab96b93d26404f3f0cb0 Mon Sep 17 00:00:00 2001 From: Deepak Rangarajan Date: Tue, 23 Jun 2020 10:26:05 -0400 Subject: [PATCH 1/9] Switch from assert to throw, add check for polyhedron --- include/csg_types.hpp | 9 +++++++-- src/csg/cgal_helper_polyhedron.cpp | 6 ++++++ src/csg/parser.cpp | 17 ++++++++++++----- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/include/csg_types.hpp b/include/csg_types.hpp index 7004c81..8173e63 100644 --- a/include/csg_types.hpp +++ b/include/csg_types.hpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -61,7 +62,9 @@ public: Polyhedron(const std::vector> &points, const std::vector> &faces) { for (const auto &pt : points) { - assert(pt.size() == 3); + if (pt.size() != 3) + throw std::runtime_error("Error parsing polyhedron. Check input!"); + m_points.push_back({pt[0], pt[1], pt[2]}); } for (const auto &f : faces) { @@ -86,7 +89,9 @@ public: Polygon(const std::vector> &points, const std::vector &path) { for (const auto &pt : points) { - assert(pt.size() == 2); + if (pt.size() != 2) + throw std::runtime_error("Error parsing polygon. Check input!"); + m_points.push_back({pt[0], pt[1]}); } for (const auto &p : path) { diff --git a/src/csg/cgal_helper_polyhedron.cpp b/src/csg/cgal_helper_polyhedron.cpp index ad43e7f..05b04e7 100644 --- a/src/csg/cgal_helper_polyhedron.cpp +++ b/src/csg/cgal_helper_polyhedron.cpp @@ -1,5 +1,7 @@ #include "csg_cgal_helper.hpp" +#include + #include #include #include @@ -46,6 +48,10 @@ public: // Add facets next for (const auto &face : m_faces) { B.begin_facet(); + if (!B.test_facet(face.begin(), face.end())) + throw std::runtime_error( + "Unable to create the polyhedron. Check input!"); + for (const auto &p_index : face) { B.add_vertex_to_facet(p_index); } diff --git a/src/csg/parser.cpp b/src/csg/parser.cpp index 7e8491e..8c9fd59 100644 --- a/src/csg/parser.cpp +++ b/src/csg/parser.cpp @@ -1,7 +1,7 @@ // standard includes -#include #include #include +#include // subproject includes #include @@ -511,7 +511,7 @@ template <> struct action { 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 std::runtime_error("Error parsing cylinder. Check input!"); } csg::Cylinder cyl; cyl.name = get_name(curr_attr); @@ -590,7 +590,8 @@ template <> struct action { std::vector> paths = {{}}; if (std::holds_alternative(curr_attr["paths"])) { - assert(std::get(curr_attr["paths"]) == UNDEFINED_STR); + if (std::get(curr_attr["paths"]) != UNDEFINED_STR) + throw std::runtime_error("Error parsing polygon. Check inputs!"); } else { paths = std::get>>(curr_attr["paths"]); } @@ -727,12 +728,18 @@ std::shared_ptr parse_csg(std::string str) { } auto st = maybe_state.value(); - assert(st.current_3d_objs.size() == 1); + if (st.current_3d_objs.size() != 1) + throw std::runtime_error("Error parsing. Check input!"); + 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 std::runtime_error( + "Error parsing. Check input!"); // Disallow empty .csg file + return std::make_shared(tree); } } // namespace csg -- GitLab From 1bda9dbfb0204475df44000336f53c00e91e57c8 Mon Sep 17 00:00:00 2001 From: Deepak Rangarajan Date: Tue, 23 Jun 2020 10:36:38 -0400 Subject: [PATCH 2/9] update throw msg --- src/csg/parser.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/csg/parser.cpp b/src/csg/parser.cpp index 8c9fd59..fdc0ce2 100644 --- a/src/csg/parser.cpp +++ b/src/csg/parser.cpp @@ -729,7 +729,8 @@ std::shared_ptr parse_csg(std::string str) { auto st = maybe_state.value(); if (st.current_3d_objs.size() != 1) - throw std::runtime_error("Error parsing. Check input!"); + throw std::runtime_error( + "Error parsing. Somehow created a bad top level object!"); Tree tree; for (auto obj : st.current_3d_objs.back()) { @@ -738,7 +739,8 @@ std::shared_ptr parse_csg(std::string str) { if (tree.top.objs.empty()) throw std::runtime_error( - "Error parsing. Check input!"); // Disallow empty .csg file + "Error parsing. Empty object tree created!"); // Disallow empty .csg + // file return std::make_shared(tree); } -- GitLab From 9935c47d4321d0794db7dd0c4b07946db231c290 Mon Sep 17 00:00:00 2001 From: Deepak Rangarajan Date: Tue, 23 Jun 2020 11:53:48 -0400 Subject: [PATCH 3/9] better exception messages --- src/csg/cgal_helper_polyhedron.cpp | 2 +- src/csg/parser.cpp | 13 ++++++------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/csg/cgal_helper_polyhedron.cpp b/src/csg/cgal_helper_polyhedron.cpp index 05b04e7..40c8f3c 100644 --- a/src/csg/cgal_helper_polyhedron.cpp +++ b/src/csg/cgal_helper_polyhedron.cpp @@ -50,7 +50,7 @@ public: B.begin_facet(); if (!B.test_facet(face.begin(), face.end())) throw std::runtime_error( - "Unable to create the polyhedron. Check input!"); + "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/parser.cpp b/src/csg/parser.cpp index fdc0ce2..2554373 100644 --- a/src/csg/parser.cpp +++ b/src/csg/parser.cpp @@ -509,9 +509,8 @@ 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; - throw std::runtime_error("Error parsing cylinder. Check input!"); + throw std::runtime_error( + " ERROR: cannot specify both r and (r1 or r2); ambiguous "); } csg::Cylinder cyl; cyl.name = get_name(curr_attr); @@ -590,8 +589,9 @@ template <> struct action { std::vector> paths = {{}}; if (std::holds_alternative(curr_attr["paths"])) { - if (std::get(curr_attr["paths"]) != UNDEFINED_STR) - throw std::runtime_error("Error parsing polygon. Check inputs!"); + auto paths_str = std::get(curr_attr["paths"]; + if (paths_str != UNDEFINED_STR) + throw std::runtime_error("Error parsing polygon. paths = " + paths_str + " not recognized" ); } else { paths = std::get>>(curr_attr["paths"]); } @@ -739,8 +739,7 @@ std::shared_ptr parse_csg(std::string str) { if (tree.top.objs.empty()) throw std::runtime_error( - "Error parsing. Empty object tree created!"); // Disallow empty .csg - // file + "Error parsing. Empty csg file"); // Disallow empty .csg file return std::make_shared(tree); } -- GitLab From ad682f0df466f1ffa000e38cb00613abc8db9fae Mon Sep 17 00:00:00 2001 From: Deepak Rangarajan Date: Tue, 23 Jun 2020 12:00:06 -0400 Subject: [PATCH 4/9] fix --- src/csg/parser.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/csg/parser.cpp b/src/csg/parser.cpp index 2554373..8344ac4 100644 --- a/src/csg/parser.cpp +++ b/src/csg/parser.cpp @@ -589,9 +589,10 @@ template <> struct action { std::vector> paths = {{}}; if (std::holds_alternative(curr_attr["paths"])) { - auto paths_str = std::get(curr_attr["paths"]; + auto paths_str = std::get(curr_attr["paths"]); if (paths_str != UNDEFINED_STR) - throw std::runtime_error("Error parsing polygon. paths = " + paths_str + " not recognized" ); + throw std::runtime_error("Error parsing polygon. paths = " + paths_str + + " not recognized"); } else { paths = std::get>>(curr_attr["paths"]); } -- GitLab From 2e5dbfd418df785a6d36e1c56c988cc398feb837 Mon Sep 17 00:00:00 2001 From: Deepak Rangarajan Date: Tue, 23 Jun 2020 12:23:05 -0400 Subject: [PATCH 5/9] replace exception with assert --- src/csg/parser.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/csg/parser.cpp b/src/csg/parser.cpp index 8344ac4..1d3007e 100644 --- a/src/csg/parser.cpp +++ b/src/csg/parser.cpp @@ -729,9 +729,7 @@ std::shared_ptr parse_csg(std::string str) { } auto st = maybe_state.value(); - if (st.current_3d_objs.size() != 1) - throw std::runtime_error( - "Error parsing. Somehow created a bad top level object!"); + assert(st.current_3d_objs.size() == 1); Tree tree; for (auto obj : st.current_3d_objs.back()) { -- GitLab From 5485fa3d4a25d35a351902d29cb3cfded9b9a373 Mon Sep 17 00:00:00 2001 From: Deepak Rangarajan Date: Tue, 23 Jun 2020 16:57:54 -0400 Subject: [PATCH 6/9] add custom exception class --- src/csg/CMakeLists.txt | 1 + src/csg/exception.cpp | 27 +++++++++++++++++++++++++++ src/csg/meson.build | 1 + src/csg_exception.hpp | 24 ++++++++++++++++++++++++ 4 files changed, 53 insertions(+) create mode 100644 src/csg/exception.cpp create mode 100644 src/csg_exception.hpp diff --git a/src/csg/CMakeLists.txt b/src/csg/CMakeLists.txt index f3d2aba..669bca3 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/exception.cpp b/src/csg/exception.cpp new file mode 100644 index 0000000..f4745e3 --- /dev/null +++ b/src/csg/exception.cpp @@ -0,0 +1,27 @@ +#include + +#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 6d81be4..d346176 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_exception.hpp b/src/csg_exception.hpp new file mode 100644 index 0000000..2e7858a --- /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 -- GitLab From 639b59ab49c6b356bc935cb2aa174c93c40826b4 Mon Sep 17 00:00:00 2001 From: Deepak Rangarajan Date: Tue, 23 Jun 2020 17:12:42 -0400 Subject: [PATCH 7/9] switch to new exception --- include/csg_types.hpp | 9 ++------- src/csg/exception.cpp | 2 +- src/csg/parser.cpp | 12 +++++++----- 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/include/csg_types.hpp b/include/csg_types.hpp index 8173e63..7004c81 100644 --- a/include/csg_types.hpp +++ b/include/csg_types.hpp @@ -7,7 +7,6 @@ #include #include #include -#include #include #include #include @@ -62,9 +61,7 @@ public: Polyhedron(const std::vector> &points, const std::vector> &faces) { for (const auto &pt : points) { - if (pt.size() != 3) - throw std::runtime_error("Error parsing polyhedron. Check input!"); - + assert(pt.size() == 3); m_points.push_back({pt[0], pt[1], pt[2]}); } for (const auto &f : faces) { @@ -89,9 +86,7 @@ public: Polygon(const std::vector> &points, const std::vector &path) { for (const auto &pt : points) { - if (pt.size() != 2) - throw std::runtime_error("Error parsing polygon. Check input!"); - + assert(pt.size() == 2); m_points.push_back({pt[0], pt[1]}); } for (const auto &p : path) { diff --git a/src/csg/exception.cpp b/src/csg/exception.cpp index f4745e3..33cde00 100644 --- a/src/csg/exception.cpp +++ b/src/csg/exception.cpp @@ -1,4 +1,4 @@ -#include +#include "csg_exception.hpp" #include #include diff --git a/src/csg/parser.cpp b/src/csg/parser.cpp index 1d3007e..25ccfb4 100644 --- a/src/csg/parser.cpp +++ b/src/csg/parser.cpp @@ -7,6 +7,7 @@ #include // includes +#include "csg_exception.hpp" #include "csg_types.hpp" using namespace tao::pegtl; @@ -509,7 +510,8 @@ template <> struct action { if (curr_attr.count("r")) { // proper cylinder if (curr_attr.count("r1") || curr_attr.count("r2")) { - throw std::runtime_error( + throw csg::Exception( + "action", " ERROR: cannot specify both r and (r1 or r2); ambiguous "); } csg::Cylinder cyl; @@ -591,8 +593,8 @@ template <> struct action { if (std::holds_alternative(curr_attr["paths"])) { auto paths_str = std::get(curr_attr["paths"]); if (paths_str != UNDEFINED_STR) - throw std::runtime_error("Error parsing polygon. paths = " + paths_str + - " not recognized"); + throw csg::Exception("action", + "paths = " + paths_str + " not recognized"); } else { paths = std::get>>(curr_attr["paths"]); } @@ -737,8 +739,8 @@ std::shared_ptr parse_csg(std::string str) { } if (tree.top.objs.empty()) - throw std::runtime_error( - "Error parsing. Empty csg file"); // Disallow empty .csg file + throw csg::Exception("parse_csg", + "Empty csg file"); // Disallow empty .csg file return std::make_shared(tree); } -- GitLab From 8e2c88a2082c1f799c58c7258d365445e022be71 Mon Sep 17 00:00:00 2001 From: Deepak Rangarajan Date: Tue, 23 Jun 2020 17:33:34 -0400 Subject: [PATCH 8/9] Move assert checks into parser exceptions --- include/csg_types.hpp | 18 ++++++------------ src/csg/parser.cpp | 18 ++++++++++++++++-- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/include/csg_types.hpp b/include/csg_types.hpp index 7004c81..2905794 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/parser.cpp b/src/csg/parser.cpp index 25ccfb4..fc57aab 100644 --- a/src/csg/parser.cpp +++ b/src/csg/parser.cpp @@ -586,9 +586,16 @@ 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"])) { auto paths_str = std::get(curr_attr["paths"]); @@ -620,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); -- GitLab From ccc2ede92270b3d7f7fe1d7356f8564b156cbe81 Mon Sep 17 00:00:00 2001 From: Deepak Rangarajan Date: Tue, 23 Jun 2020 17:54:16 -0400 Subject: [PATCH 9/9] switch exception type --- src/csg/cgal_helper_polyhedron.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/csg/cgal_helper_polyhedron.cpp b/src/csg/cgal_helper_polyhedron.cpp index 40c8f3c..2cc5bf9 100644 --- a/src/csg/cgal_helper_polyhedron.cpp +++ b/src/csg/cgal_helper_polyhedron.cpp @@ -1,6 +1,5 @@ #include "csg_cgal_helper.hpp" - -#include +#include "csg_exception.hpp" #include #include @@ -49,7 +48,8 @@ public: for (const auto &face : m_faces) { B.begin_facet(); if (!B.test_facet(face.begin(), face.end())) - throw std::runtime_error( + throw csg::Exception( + "Polyhedron builder", "Unable to create the polyhedron. test_facet failed. Check input!"); for (const auto &p_index : face) { -- GitLab