#include "internal_primitive_desc.hpp" // =========================================================================== template struct primitive_descriptor_meta; template <> struct primitive_descriptor_meta { using internal_type = internal::constant; static constexpr primitive_type type = PRIMITIVE_TYPE_CONSTANT; }; template <> struct primitive_descriptor_meta { using internal_type = internal::plane; static constexpr primitive_type type = PRIMITIVE_TYPE_PLANE; }; template <> struct primitive_descriptor_meta { using internal_type = internal::sphere; static constexpr primitive_type type = PRIMITIVE_TYPE_SPHERE; }; template <> struct primitive_descriptor_meta { using internal_type = internal::cylinder; static constexpr primitive_type type = PRIMITIVE_TYPE_CYLINDER; }; template <> struct primitive_descriptor_meta { using internal_type = internal::cone; static constexpr primitive_type type = PRIMITIVE_TYPE_CONE; }; template <> struct primitive_descriptor_meta { using internal_type = internal::box; static constexpr primitive_type type = PRIMITIVE_TYPE_BOX; }; template <> struct primitive_descriptor_meta { using internal_type = internal::mesh; static constexpr primitive_type type = PRIMITIVE_TYPE_MESH; }; template <> struct primitive_descriptor_meta { using internal_type = internal::extrude_polyline; static constexpr primitive_type type = PRIMITIVE_TYPE_EXTRUDE_POLYLINE; }; template <> struct primitive_descriptor_meta { using internal_type = internal::extrude_helixline; static constexpr primitive_type type = PRIMITIVE_TYPE_EXTRUDE_HELIXLINE; }; // =========================================================================== primitive_node_t::primitive_node_t(const legal_primitive_descriptor_t &descriptor) noexcept { std::visit( [this](auto &&desc) -> void { using T = std::decay_t; using internal_type = typename primitive_descriptor_meta::internal_type; this->desc = ::malloc(sizeof(internal_type)); auto handle = new (this->desc) internal_type(desc, this->aabb); this->type = primitive_descriptor_meta::type; }, descriptor); } primitive_node_t::primitive_node_t(legal_primitive_descriptor_t &&descriptor) noexcept { std::visit( [this](auto &&desc) { using T = std::decay_t; using internal_type = typename primitive_descriptor_meta::internal_type; this->desc = ::malloc(sizeof(internal_type)); auto handle = new (this->desc) internal_type(std::move(desc), this->aabb); this->type = primitive_descriptor_meta::type; }, std::move(descriptor)); } primitive_node_t::~primitive_node_t() noexcept { if (this->desc == nullptr) return; if (this->type == PRIMITIVE_TYPE_MESH) static_cast(this->desc)->~mesh(); else if (this->type == PRIMITIVE_TYPE_EXTRUDE_POLYLINE) static_cast(this->desc)->~extrude_polyline(); else if (this->type == PRIMITIVE_TYPE_EXTRUDE_HELIXLINE) static_cast(this->desc)->~extrude_helixline(); ::free(this->desc); this->desc = nullptr; } template process_return_type_t primitive_node_t::evaluate([[maybe_unused]] const Eigen::Ref &point) const { switch (this->type) { case PRIMITIVE_TYPE_CONSTANT: return static_cast(this->desc)->evaluate(point); case PRIMITIVE_TYPE_PLANE: return static_cast(this->desc)->evaluate(point); case PRIMITIVE_TYPE_SPHERE: return static_cast(this->desc)->evaluate(point); case PRIMITIVE_TYPE_CYLINDER: return static_cast(this->desc)->evaluate(point); case PRIMITIVE_TYPE_CONE: return static_cast(this->desc)->evaluate(point); case PRIMITIVE_TYPE_BOX: return static_cast(this->desc)->evaluate(point); case PRIMITIVE_TYPE_MESH: return static_cast(this->desc)->evaluate(point); case PRIMITIVE_TYPE_EXTRUDE_POLYLINE: return static_cast(this->desc)->evaluate(point); case PRIMITIVE_TYPE_EXTRUDE_HELIXLINE: return static_cast(this->desc)->evaluate(point); default: throw std::runtime_error("Invalid primitive type"); } } template process_return_type_t primitive_node_t::evaluate( [[maybe_unused]] const Eigen::Ref &point) const; template process_return_type_t primitive_node_t::evaluate( [[maybe_unused]] const Eigen::Ref &point) const;