|
|
@ -61,14 +61,38 @@ struct primitive_descriptor_meta<extrude_helixline_descriptor_t> { |
|
|
|
|
|
|
|
// ===========================================================================
|
|
|
|
|
|
|
|
static inline void free_data_block(void *ptr, primitive_type type) noexcept |
|
|
|
{ |
|
|
|
if (ptr == nullptr) return; |
|
|
|
|
|
|
|
#define PRIM_DTOR(prim_type, internal_prim_type) \ |
|
|
|
case prim_type: static_cast<internal::internal_prim_type *>(ptr)->~internal_prim_type(); break |
|
|
|
|
|
|
|
switch (type) { |
|
|
|
PRIM_DTOR(PRIMITIVE_TYPE_CONSTANT, constant); |
|
|
|
PRIM_DTOR(PRIMITIVE_TYPE_PLANE, plane); |
|
|
|
PRIM_DTOR(PRIMITIVE_TYPE_SPHERE, sphere); |
|
|
|
PRIM_DTOR(PRIMITIVE_TYPE_CYLINDER, cylinder); |
|
|
|
PRIM_DTOR(PRIMITIVE_TYPE_CONE, cone); |
|
|
|
PRIM_DTOR(PRIMITIVE_TYPE_BOX, box); |
|
|
|
PRIM_DTOR(PRIMITIVE_TYPE_MESH, mesh); |
|
|
|
PRIM_DTOR(PRIMITIVE_TYPE_EXTRUDE_POLYLINE, extrude_polyline); |
|
|
|
PRIM_DTOR(PRIMITIVE_TYPE_EXTRUDE_HELIXLINE, extrude_helixline); |
|
|
|
} |
|
|
|
|
|
|
|
#undef PRIM_DTOR |
|
|
|
|
|
|
|
::free(ptr); |
|
|
|
} |
|
|
|
|
|
|
|
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->data = ::malloc(sizeof(internal_type)); |
|
|
|
auto handle = new (this->data) internal_type(desc, this->aabb); |
|
|
|
this->type = primitive_descriptor_meta<T>::type; |
|
|
|
}, |
|
|
|
descriptor); |
|
|
@ -80,59 +104,82 @@ primitive_node_t::primitive_node_t(legal_primitive_descriptor_t &&descriptor) no |
|
|
|
[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->data = ::malloc(sizeof(internal_type)); |
|
|
|
auto handle = new (this->data) internal_type(std::move(desc), this->aabb); |
|
|
|
this->type = primitive_descriptor_meta<T>::type; |
|
|
|
}, |
|
|
|
std::move(descriptor)); |
|
|
|
} |
|
|
|
|
|
|
|
primitive_node_t::~primitive_node_t() noexcept |
|
|
|
primitive_node_t::primitive_node_t(primitive_node_t &&other) noexcept |
|
|
|
: aabb(std::move(other.aabb)), data(other.data), type(other.type) |
|
|
|
{ |
|
|
|
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; |
|
|
|
other.data = nullptr; |
|
|
|
} |
|
|
|
|
|
|
|
primitive_node_t::~primitive_node_t() noexcept { free_data_block(this->data, this->type); } |
|
|
|
|
|
|
|
primitive_node_t &primitive_node_t::operator=(primitive_node_t &&other) noexcept |
|
|
|
{ |
|
|
|
auto old_ptr = std::exchange(this->data, other.data); |
|
|
|
free_data_block(old_ptr, type); |
|
|
|
this->type = other.type; |
|
|
|
|
|
|
|
other.data = nullptr; |
|
|
|
|
|
|
|
return *this; |
|
|
|
} |
|
|
|
|
|
|
|
void primitive_node_t::swap(primitive_node_t &other) noexcept |
|
|
|
{ |
|
|
|
using std::swap; |
|
|
|
swap(this->aabb, other.aabb); |
|
|
|
swap(this->data, other.data); |
|
|
|
swap(this->type, other.type); |
|
|
|
} |
|
|
|
|
|
|
|
double primitive_node_t::evaluate_sdf([[maybe_unused]] const Eigen::Ref<const Eigen::Vector3d> &point) const |
|
|
|
{ |
|
|
|
assert(this->data); |
|
|
|
|
|
|
|
#define PRIM_EVAL_SDF(prim_type, internal_prim_type) \ |
|
|
|
case prim_type: return static_cast<internal::internal_prim_type *>(this->data)->evaluate_sdf(point) |
|
|
|
|
|
|
|
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); |
|
|
|
PRIM_EVAL_SDF(PRIMITIVE_TYPE_CONSTANT, constant); |
|
|
|
PRIM_EVAL_SDF(PRIMITIVE_TYPE_PLANE, plane); |
|
|
|
PRIM_EVAL_SDF(PRIMITIVE_TYPE_SPHERE, sphere); |
|
|
|
PRIM_EVAL_SDF(PRIMITIVE_TYPE_CYLINDER, cylinder); |
|
|
|
PRIM_EVAL_SDF(PRIMITIVE_TYPE_CONE, cone); |
|
|
|
PRIM_EVAL_SDF(PRIMITIVE_TYPE_BOX, box); |
|
|
|
PRIM_EVAL_SDF(PRIMITIVE_TYPE_MESH, mesh); |
|
|
|
PRIM_EVAL_SDF(PRIMITIVE_TYPE_EXTRUDE_POLYLINE, extrude_polyline); |
|
|
|
PRIM_EVAL_SDF(PRIMITIVE_TYPE_EXTRUDE_HELIXLINE, extrude_helixline); |
|
|
|
default: throw std::runtime_error("Invalid primitive type"); |
|
|
|
} |
|
|
|
|
|
|
|
#undef PRIM_EVAL_SDF |
|
|
|
} |
|
|
|
|
|
|
|
Eigen::Vector3d primitive_node_t::evaluate_cpm([[maybe_unused]] const Eigen::Ref<const Eigen::Vector3d> &point) const |
|
|
|
{ |
|
|
|
assert(this->data); |
|
|
|
|
|
|
|
#define PRIM_EVAL_CPM(prim_type, internal_prim_type) \ |
|
|
|
case prim_type: return static_cast<internal::internal_prim_type *>(this->data)->evaluate_cpm(point) |
|
|
|
|
|
|
|
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); |
|
|
|
PRIM_EVAL_CPM(PRIMITIVE_TYPE_CONSTANT, constant); |
|
|
|
PRIM_EVAL_CPM(PRIMITIVE_TYPE_PLANE, plane); |
|
|
|
PRIM_EVAL_CPM(PRIMITIVE_TYPE_SPHERE, sphere); |
|
|
|
PRIM_EVAL_CPM(PRIMITIVE_TYPE_CYLINDER, cylinder); |
|
|
|
PRIM_EVAL_CPM(PRIMITIVE_TYPE_CONE, cone); |
|
|
|
PRIM_EVAL_CPM(PRIMITIVE_TYPE_BOX, box); |
|
|
|
PRIM_EVAL_CPM(PRIMITIVE_TYPE_MESH, mesh); |
|
|
|
PRIM_EVAL_CPM(PRIMITIVE_TYPE_EXTRUDE_POLYLINE, extrude_polyline); |
|
|
|
PRIM_EVAL_CPM(PRIMITIVE_TYPE_EXTRUDE_HELIXLINE, extrude_helixline); |
|
|
|
default: throw std::runtime_error("Invalid primitive type"); |
|
|
|
} |
|
|
|
|
|
|
|
#undef PRIM_EVAL_CPM |
|
|
|
} |