You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

138 lines
6.3 KiB

#include "internal_primitive_desc.hpp"
// ===========================================================================
template <typename T>
struct primitive_descriptor_meta;
template <>
struct primitive_descriptor_meta<constant_descriptor_t> {
using internal_type = internal::constant;
static constexpr primitive_type type = PRIMITIVE_TYPE_CONSTANT;
};
template <>
struct primitive_descriptor_meta<plane_descriptor_t> {
using internal_type = internal::plane;
static constexpr primitive_type type = PRIMITIVE_TYPE_PLANE;
};
template <>
struct primitive_descriptor_meta<sphere_descriptor_t> {
using internal_type = internal::sphere;
static constexpr primitive_type type = PRIMITIVE_TYPE_SPHERE;
};
template <>
struct primitive_descriptor_meta<cylinder_descriptor_t> {
using internal_type = internal::cylinder;
static constexpr primitive_type type = PRIMITIVE_TYPE_CYLINDER;
};
template <>
struct primitive_descriptor_meta<cone_descriptor_t> {
using internal_type = internal::cone;
static constexpr primitive_type type = PRIMITIVE_TYPE_CONE;
};
template <>
struct primitive_descriptor_meta<box_descriptor_t> {
using internal_type = internal::box;
static constexpr primitive_type type = PRIMITIVE_TYPE_BOX;
};
template <>
struct primitive_descriptor_meta<mesh_descriptor_t> {
using internal_type = internal::mesh;
static constexpr primitive_type type = PRIMITIVE_TYPE_MESH;
};
template <>
struct primitive_descriptor_meta<extrude_polyline_descriptor_t> {
using internal_type = internal::extrude_polyline;
static constexpr primitive_type type = PRIMITIVE_TYPE_EXTRUDE_POLYLINE;
};
template <>
struct primitive_descriptor_meta<extrude_helixline_descriptor_t> {
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<decltype(desc)>;
using internal_type = typename primitive_descriptor_meta<T>::internal_type;
this->desc = ::malloc(sizeof(internal_type));
auto handle = new (this->desc) internal_type(desc, this->aabb);
this->type = primitive_descriptor_meta<T>::type;
},
descriptor);
}
primitive_node_t::primitive_node_t(legal_primitive_descriptor_t &&descriptor) noexcept
{
std::visit(
[this](auto &&desc) {
using T = std::decay_t<decltype(desc)>;
using internal_type = typename primitive_descriptor_meta<T>::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<T>::type;
},
std::move(descriptor));
}
primitive_node_t::~primitive_node_t() noexcept
{
if (this->desc == nullptr) return;
if (this->type == PRIMITIVE_TYPE_MESH)
static_cast<internal::mesh *>(this->desc)->~mesh();
else if (this->type == PRIMITIVE_TYPE_EXTRUDE_POLYLINE)
static_cast<internal::extrude_polyline *>(this->desc)->~extrude_polyline();
else if (this->type == PRIMITIVE_TYPE_EXTRUDE_HELIXLINE)
static_cast<internal::extrude_helixline *>(this->desc)->~extrude_helixline();
::free(this->desc);
this->desc = nullptr;
}
double primitive_node_t::evaluate_sdf([[maybe_unused]] const Eigen::Ref<const Eigen::Vector3d> &point) const
{
switch (this->type) {
case PRIMITIVE_TYPE_CONSTANT: return static_cast<const internal::constant *>(this->desc)->evaluate_sdf(point);
case PRIMITIVE_TYPE_PLANE: return static_cast<const internal::plane *>(this->desc)->evaluate_sdf(point);
case PRIMITIVE_TYPE_SPHERE: return static_cast<const internal::sphere *>(this->desc)->evaluate_sdf(point);
case PRIMITIVE_TYPE_CYLINDER: return static_cast<const internal::cylinder *>(this->desc)->evaluate_sdf(point);
case PRIMITIVE_TYPE_CONE: return static_cast<const internal::cone *>(this->desc)->evaluate_sdf(point);
case PRIMITIVE_TYPE_BOX: return static_cast<const internal::box *>(this->desc)->evaluate_sdf(point);
case PRIMITIVE_TYPE_MESH: return static_cast<const internal::mesh *>(this->desc)->evaluate_sdf(point);
case PRIMITIVE_TYPE_EXTRUDE_POLYLINE:
return static_cast<const internal::extrude_polyline *>(this->desc)->evaluate_sdf(point);
case PRIMITIVE_TYPE_EXTRUDE_HELIXLINE:
return static_cast<const internal::extrude_helixline *>(this->desc)->evaluate_sdf(point);
default: throw std::runtime_error("Invalid primitive type");
}
}
Eigen::Vector3d primitive_node_t::evaluate_cpm([[maybe_unused]] const Eigen::Ref<const Eigen::Vector3d> &point) const
{
switch (this->type) {
case PRIMITIVE_TYPE_CONSTANT: return static_cast<const internal::constant *>(this->desc)->evaluate_cpm(point);
case PRIMITIVE_TYPE_PLANE: return static_cast<const internal::plane *>(this->desc)->evaluate_cpm(point);
case PRIMITIVE_TYPE_SPHERE: return static_cast<const internal::sphere *>(this->desc)->evaluate_cpm(point);
case PRIMITIVE_TYPE_CYLINDER: return static_cast<const internal::cylinder *>(this->desc)->evaluate_cpm(point);
case PRIMITIVE_TYPE_CONE: return static_cast<const internal::cone *>(this->desc)->evaluate_cpm(point);
case PRIMITIVE_TYPE_BOX: return static_cast<const internal::box *>(this->desc)->evaluate_cpm(point);
case PRIMITIVE_TYPE_MESH: return static_cast<const internal::mesh *>(this->desc)->evaluate_cpm(point);
case PRIMITIVE_TYPE_EXTRUDE_POLYLINE:
return static_cast<const internal::extrude_polyline *>(this->desc)->evaluate_cpm(point);
case PRIMITIVE_TYPE_EXTRUDE_HELIXLINE:
return static_cast<const internal::extrude_helixline *>(this->desc)->evaluate_cpm(point);
default: throw std::runtime_error("Invalid primitive type");
}
}