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.
605 lines
22 KiB
605 lines
22 KiB
#pragma once
|
|
#include <iostream>
|
|
|
|
#include <stdint.h>
|
|
#include <variant>
|
|
#include <optional>
|
|
#include <data/data_type.hpp>
|
|
#include <math/math_defs.h>
|
|
|
|
typedef enum {
|
|
// PRIMITIVE_TYPE_CONSTANT,
|
|
// PRIMITIVE_TYPE_PLANE,
|
|
PRIMITIVE_TYPE_SPHERE,
|
|
PRIMITIVE_TYPE_CYLINDER,
|
|
PRIMITIVE_TYPE_CONE,
|
|
PRIMITIVE_TYPE_BOX,
|
|
// PRIMITIVE_TYPE_MESH,
|
|
PRIMITIVE_TYPE_EXTRUDE_POLYLINE,
|
|
PRIMITIVE_TYPE_EXTRUDE_HELIXLINE,
|
|
PRIMITIVE_TYPE_MAX_COUNT
|
|
} primitive_type;
|
|
|
|
// // Placeholder, currently used to represent empty body
|
|
// typedef struct {
|
|
// double value; // Use 0 to represent an empty body
|
|
// } constant_descriptor_t;
|
|
|
|
// Plane descriptor
|
|
typedef struct {
|
|
//vector3d point; // The base point of the plane
|
|
//vector3d normal; // The normal of the plane
|
|
vector2d local_aabb_min;
|
|
vector2d local_aabb_max;
|
|
} plane_descriptor_t;
|
|
|
|
// Sphere descriptor
|
|
typedef struct {
|
|
vector3d center; // The center of the sphere
|
|
double radius; // The radius of the sphere
|
|
} sphere_descriptor_t;
|
|
|
|
// Cylinder descriptor
|
|
typedef struct {
|
|
vector3d bottom_origin; // The origin of bottom face of the cylinder
|
|
double radius; // The radius of the cylinder
|
|
double height; // The total height of the cylinder
|
|
vector3d offset; // The vector from the origion of bottom face to the origion of the top face
|
|
} cylinder_descriptor_t;
|
|
|
|
typedef struct {
|
|
vector3d top_point; // The origin of top face of the cone
|
|
vector3d bottom_point; // The origin of bottom face of the cone
|
|
double radius1; // The radius of the top face
|
|
double radius2; // The radius of the bottom face
|
|
} cone_descriptor_t;
|
|
|
|
typedef struct {
|
|
vector3d center; // The center of the box
|
|
vector3d half_size; // The { half_length, half_width, half_height} of the box
|
|
} box_descriptor_t;
|
|
|
|
// // Mesh descriptor
|
|
// typedef struct {
|
|
// uint32_t begin_index;
|
|
// uint32_t vertex_count;
|
|
// } polygon_face_descriptor_t;
|
|
|
|
// typedef struct {
|
|
// uint32_t point_number; // The point number of the mesh
|
|
// uint32_t face_number; // The face number of the mesh
|
|
// vector3d* points; // The points of the mesh
|
|
// uint32_t* indices; // The indices from face to point
|
|
// polygon_face_descriptor_t* faces; // Two-dimensional array, Use [begin index, length] to represent a face
|
|
// } mesh_descriptor_t;
|
|
|
|
// Extrude descriptor
|
|
// CAUTION: when looking into the polyline from -{reference_normal} direction, all points should be arranged in counter
|
|
// clockwise order
|
|
// CAUTION: iff {is_closed} is true, then {point_number} == {bulge_number} should be agreed; iff {is_closed} is false,
|
|
// then {point_number} == {bulge_number} + 1 should be agreed.
|
|
typedef struct {
|
|
uint32_t point_number; // The point number of the polyline
|
|
vector3d* points; // The points of the polyline
|
|
uint32_t bulge_number; // The bulge number of the polyline
|
|
double* bulges; // The bulge of each edge
|
|
vector3d reference_normal; // The reference normal of the polyline
|
|
bool is_close; // Whether the polyline is close
|
|
} polyline_descriptor_t;
|
|
|
|
typedef struct {
|
|
vector3d axis_start; // The start point of the helix line
|
|
vector3d axis_end; // The end point of the helix line
|
|
double radius; // The radius of the helix line
|
|
double advance_per_round; // The advance per round of the helix line
|
|
vector3d start_direction; // The direction from axisStart to start of the helix line
|
|
bool is_righthanded; // {axis_start -> axis_end} as upward direction
|
|
} helixline_descriptor_t;
|
|
|
|
// 独立的 Profile Descriptor
|
|
typedef struct {
|
|
uint32_t point_number;
|
|
vector3d* points;
|
|
uint32_t bulge_number;
|
|
double* bulges;
|
|
vector3d reference_normal;
|
|
bool is_close;
|
|
} profile_descriptor_t; // (与 polyline_descriptor_t 完全相同)
|
|
|
|
// Axis Descriptor
|
|
typedef enum { AXIS_TYPE_POLYLINE, AXIS_TYPE_HELIXLINE } axis_type_t;
|
|
|
|
typedef struct {
|
|
axis_type_t type;
|
|
|
|
union {
|
|
polyline_descriptor_t polyline;
|
|
helixline_descriptor_t helixline;
|
|
} data;
|
|
} axis_descriptor_t;
|
|
|
|
// Note : In profiles, The first polyline is outer boundary, and the ohters is internal holes
|
|
typedef struct {
|
|
uint32_t profile_number; // The profiles number of the extruded solid
|
|
polyline_descriptor_t* profiles; // The profiles of the extruded solid
|
|
polyline_descriptor_t axis; // The axis of the extruded solid
|
|
} extrude_polyline_descriptor_t;
|
|
|
|
typedef struct {
|
|
uint32_t profile_number; // The profiles number of the extruded solid
|
|
polyline_descriptor_t* profiles; // The profiles of the extruded solid
|
|
helixline_descriptor_t axis; // The axis of the extruded solid
|
|
} extrude_helixline_descriptor_t;
|
|
|
|
namespace descriptor_defaults
|
|
{
|
|
// @brief 单位平面:center=(0,0,0), r=1.0
|
|
inline constexpr plane_descriptor_t unit_plane{
|
|
vector2d{-1, -1}, // local_aabb_min
|
|
vector2d{1, 1}, // local_aabb_max
|
|
};
|
|
|
|
// @brief 单位球:center=(0,0,0), r=1.0
|
|
inline constexpr sphere_descriptor_t unit_sphere{
|
|
vector3d{0, 0, 0},
|
|
1.0
|
|
};
|
|
|
|
/// @brief 单位圆柱:底面原点在(0,0,0),半径=1.0,高度=1.0
|
|
inline constexpr cylinder_descriptor_t unit_cylinder{
|
|
{0.0, 0.0, 0.0}, // bottom_origin: 原点在(0,0,0)
|
|
1.0, // radius: 半径为1.0
|
|
1.0, // height: 高度为1.0
|
|
{0.0, 0.0, 1.0} // offset: 沿Z轴向上偏移1.0
|
|
};
|
|
|
|
/// @brief 单位正方形 profile
|
|
inline const polyline_descriptor_t unit_square_profile = [] {
|
|
static const std::vector<vector3d> points = {
|
|
//{-0.5, -0.5, 0.0},
|
|
//{0.5, -0.5, 0.0},
|
|
//{0.5, 0.5, 0.0},
|
|
//{-0.5, 0.5, 0.0}
|
|
|
|
//{-1.5, -1.5, 0.0},
|
|
//{1.5, -1.5, 0.0},
|
|
//{0.0, 6.0, 0.0}
|
|
|
|
//{0.0, 0.430871, -0.902414}, // 局部坐标: (1, 1)
|
|
//{0.0, -0.430871, 0.902414 }, // 局部坐标: (-1, 1)
|
|
//{2.0, -0.430871, 0.902414 }, // 局部坐标: (-1, -1)
|
|
//{2.0, 0.430871, -0.902414} // 局部坐标: (1, -1)
|
|
|
|
{0.0, 0.430871, -0.902414},
|
|
{0.0, -0.430871, 0.902414 },
|
|
{2.0, 0.1, -0.6},
|
|
{2.0, 0.430871, -0.902414}
|
|
|
|
//{0.0, 0.430871, -0.902414}, // 局部坐标: (1, 1)
|
|
//{1.0, -0.430871, 0.902414 },
|
|
//{6.0, 0.430871, -0.902414} // 局部坐标: (1, -1)
|
|
};
|
|
// static const std::vector<double> bulges = {0.4, -0.8, 1.0, -0.5};
|
|
// static const std::vector<double> bulges = {-0.4, 0.8, 0.0, -0.5}; // polyline ERROR
|
|
// static const std::vector<double> bulges = {0.0, 0.0, -0.5, 0.0}; // helixline ERROR
|
|
static const std::vector<double> bulges = {0.0, 0.0, 1.0, 0.0}; // helixline ERROR
|
|
polyline_descriptor_t desc;
|
|
desc.point_number = 4;
|
|
desc.points = const_cast<vector3d*>(points.data());
|
|
desc.bulge_number = 4;
|
|
desc.bulges = const_cast<double*>(bulges.data());
|
|
desc.reference_normal = {0, 0, 1};
|
|
desc.is_close = true;
|
|
return desc;
|
|
}();
|
|
|
|
inline const std::vector<vector3d> unit_axis_points = {
|
|
{0.0, 0.0, -0.5},
|
|
{0.0, 6.0, 6.0 }
|
|
//{4.0, 0.0, 1.0}
|
|
//{4.0, 0.0, -1.0}
|
|
};
|
|
|
|
inline const std::vector<double> unit_axis_bulges = {0.0};
|
|
|
|
inline const polyline_descriptor_t unit_polyline_axis = [] {
|
|
polyline_descriptor_t desc;
|
|
desc.point_number = 2;
|
|
desc.points = const_cast<vector3d*>(unit_axis_points.data());
|
|
desc.bulge_number = 1;
|
|
desc.bulges = const_cast<double*>(unit_axis_bulges.data());
|
|
desc.reference_normal = {0, 1, 0}; // 注意 reference_normal 要垂直与 axis 所在平面
|
|
desc.is_close = false;
|
|
return desc;
|
|
}();
|
|
|
|
inline const extrude_polyline_descriptor_t unit_extrude_polyline = [] {
|
|
extrude_polyline_descriptor_t desc;
|
|
desc.profile_number = 1;
|
|
desc.profiles = const_cast<polyline_descriptor_t*>(&unit_square_profile);
|
|
desc.axis = unit_polyline_axis;
|
|
return desc;
|
|
}();
|
|
|
|
/// @brief 单位螺旋线:默认参数
|
|
inline constexpr helixline_descriptor_t unit_helix = {
|
|
{0.0, 0.0, 0.0}, // axis_start
|
|
{0.0, 0.0, 10.0}, // axis_end
|
|
1.0, // radius
|
|
3.0, // advance_per_round
|
|
{1.0, 0.0, 0.0}, // start_direction
|
|
true // is_righthanded
|
|
};
|
|
|
|
/// @brief 单位拉伸 helixline
|
|
inline const extrude_helixline_descriptor_t unit_extrude_helixline = [] {
|
|
extrude_helixline_descriptor_t desc;
|
|
desc.profile_number = 1;
|
|
desc.profiles = const_cast<polyline_descriptor_t*>(&unit_square_profile);
|
|
desc.axis = unit_helix;
|
|
return desc;
|
|
}();
|
|
} // namespace descriptor_defaults
|
|
|
|
namespace detail
|
|
{
|
|
template <typename T>
|
|
inline void hash_combine(size_t& seed, const T& val)
|
|
{
|
|
seed ^= std::hash<T>{}(val) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
|
|
}
|
|
|
|
template <>
|
|
struct hasher<polyline_descriptor_t> {
|
|
size_t operator()(const polyline_descriptor_t& desc) const
|
|
{
|
|
size_t h = 0;
|
|
hash_combine(h, desc.point_number);
|
|
hash_combine(h, desc.bulge_number);
|
|
hash_combine(h, desc.is_close);
|
|
hash_combine(h, desc.reference_normal.x);
|
|
hash_combine(h, desc.reference_normal.y);
|
|
hash_combine(h, desc.reference_normal.z);
|
|
|
|
// 点数据
|
|
for (uint32_t i = 0; i < desc.point_number; ++i) {
|
|
hash_combine(h, desc.points[i].x);
|
|
hash_combine(h, desc.points[i].y);
|
|
hash_combine(h, desc.points[i].z);
|
|
}
|
|
|
|
// Bulge 数据
|
|
for (uint32_t i = 0; i < desc.bulge_number; ++i) { hash_combine(h, desc.bulges[i]); }
|
|
return h;
|
|
}
|
|
};
|
|
|
|
template <>
|
|
struct eq_compare<polyline_descriptor_t> {
|
|
bool operator()(const polyline_descriptor_t& lhs, const polyline_descriptor_t& rhs) const
|
|
{
|
|
if (lhs.point_number != rhs.point_number) return false;
|
|
if (lhs.bulge_number != rhs.bulge_number) return false;
|
|
if (lhs.is_close != rhs.is_close) return false;
|
|
if (lhs.reference_normal.x != rhs.reference_normal.x || lhs.reference_normal.y != rhs.reference_normal.y
|
|
|| lhs.reference_normal.z != rhs.reference_normal.z) {
|
|
return false;
|
|
}
|
|
for (uint32_t i = 0; i < lhs.point_number; ++i) {
|
|
if (lhs.points[i].x != rhs.points[i].x || lhs.points[i].y != rhs.points[i].y
|
|
|| lhs.points[i].z != rhs.points[i].z) {
|
|
return false;
|
|
}
|
|
}
|
|
for (uint32_t i = 0; i < lhs.bulge_number; ++i) {
|
|
if (lhs.bulges[i] != rhs.bulges[i]) { return false; }
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
template <>
|
|
struct hasher<helixline_descriptor_t> {
|
|
size_t operator()(const helixline_descriptor_t& desc) const
|
|
{
|
|
size_t h = 0;
|
|
hash_combine(h, desc.axis_start.x);
|
|
hash_combine(h, desc.axis_start.y);
|
|
hash_combine(h, desc.axis_start.z);
|
|
hash_combine(h, desc.axis_end.x);
|
|
hash_combine(h, desc.axis_end.y);
|
|
hash_combine(h, desc.axis_end.z);
|
|
hash_combine(h, desc.radius);
|
|
hash_combine(h, desc.advance_per_round);
|
|
hash_combine(h, desc.start_direction.x);
|
|
hash_combine(h, desc.start_direction.y);
|
|
hash_combine(h, desc.start_direction.z);
|
|
hash_combine(h, desc.is_righthanded);
|
|
return h;
|
|
}
|
|
};
|
|
|
|
template <>
|
|
struct eq_compare<helixline_descriptor_t> {
|
|
bool operator()(const helixline_descriptor_t& lhs, const helixline_descriptor_t& rhs) const
|
|
{
|
|
constexpr double eps = 1e-12;
|
|
return std::abs(lhs.axis_start.x - rhs.axis_start.x) < eps && std::abs(lhs.axis_start.y - rhs.axis_start.y) < eps
|
|
&& std::abs(lhs.axis_start.z - rhs.axis_start.z) < eps && std::abs(lhs.axis_end.x - rhs.axis_end.x) < eps
|
|
&& std::abs(lhs.axis_end.y - rhs.axis_end.y) < eps && std::abs(lhs.axis_end.z - rhs.axis_end.z) < eps
|
|
&& std::abs(lhs.radius - rhs.radius) < eps && std::abs(lhs.advance_per_round - rhs.advance_per_round) < eps
|
|
&& std::abs(lhs.start_direction.x - rhs.start_direction.x) < eps
|
|
&& std::abs(lhs.start_direction.y - rhs.start_direction.y) < eps
|
|
&& std::abs(lhs.start_direction.z - rhs.start_direction.z) < eps && lhs.is_righthanded == rhs.is_righthanded;
|
|
}
|
|
};
|
|
|
|
// Profile Descriptor Hash(复用 polyline 逻辑)
|
|
template <>
|
|
struct hasher<profile_descriptor_t> {
|
|
size_t operator()(const profile_descriptor_t& desc) const
|
|
{
|
|
// profile_descriptor_t 和 polyline_descriptor_t 布局完全相同
|
|
return hasher<polyline_descriptor_t>{}(*reinterpret_cast<const polyline_descriptor_t*>(&desc));
|
|
}
|
|
};
|
|
|
|
template <>
|
|
struct eq_compare<profile_descriptor_t> {
|
|
bool operator()(const profile_descriptor_t& lhs, const profile_descriptor_t& rhs) const
|
|
{
|
|
return eq_compare<polyline_descriptor_t>{}(*reinterpret_cast<const polyline_descriptor_t*>(&lhs),
|
|
*reinterpret_cast<const polyline_descriptor_t*>(&rhs));
|
|
}
|
|
};
|
|
|
|
// Axis Descriptor Hash
|
|
template <>
|
|
struct hasher<axis_descriptor_t> {
|
|
size_t operator()(const axis_descriptor_t& desc) const
|
|
{
|
|
size_t h = std::hash<int>{}(static_cast<int>(desc.type));
|
|
|
|
if (desc.type == AXIS_TYPE_POLYLINE) {
|
|
hash_combine(h, hasher<polyline_descriptor_t>{}(desc.data.polyline));
|
|
} else if (desc.type == AXIS_TYPE_HELIXLINE) {
|
|
hash_combine(h, hasher<helixline_descriptor_t>{}(desc.data.helixline));
|
|
}
|
|
|
|
return h;
|
|
}
|
|
};
|
|
|
|
template <>
|
|
struct eq_compare<axis_descriptor_t> {
|
|
bool operator()(const axis_descriptor_t& lhs, const axis_descriptor_t& rhs) const
|
|
{
|
|
if (lhs.type != rhs.type) return false;
|
|
|
|
if (lhs.type == AXIS_TYPE_POLYLINE) {
|
|
return eq_compare<polyline_descriptor_t>{}(lhs.data.polyline, rhs.data.polyline);
|
|
} else if (lhs.type == AXIS_TYPE_HELIXLINE) {
|
|
return eq_compare<helixline_descriptor_t>{}(lhs.data.helixline, rhs.data.helixline);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
};
|
|
|
|
template <>
|
|
struct hasher<plane_descriptor_t> {
|
|
size_t operator()(const plane_descriptor_t& desc) const
|
|
{
|
|
size_t seed = 0;
|
|
hash_combine(seed, desc.local_aabb_max.x);
|
|
hash_combine(seed, desc.local_aabb_max.y);
|
|
hash_combine(seed, desc.local_aabb_min.x);
|
|
hash_combine(seed, desc.local_aabb_min.y);
|
|
return seed;
|
|
}
|
|
};
|
|
|
|
template <>
|
|
struct eq_compare<plane_descriptor_t> {
|
|
bool operator()(const plane_descriptor_t& lhs, const plane_descriptor_t& rhs) const
|
|
{
|
|
constexpr double eps = 1e-12;
|
|
return std::abs(lhs.local_aabb_max.x - rhs.local_aabb_max.x) < eps
|
|
&& std::abs(lhs.local_aabb_max.y - rhs.local_aabb_max.y) < eps
|
|
&& std::abs(lhs.local_aabb_min.x - rhs.local_aabb_min.x) < eps
|
|
&& std::abs(lhs.local_aabb_min.y - rhs.local_aabb_min.y) < eps;
|
|
}
|
|
};
|
|
|
|
|
|
template <>
|
|
struct hasher<cylinder_descriptor_t> {
|
|
size_t operator()(const cylinder_descriptor_t& desc) const
|
|
{
|
|
size_t seed = 0;
|
|
hash_combine(seed, desc.bottom_origin.x);
|
|
hash_combine(seed, desc.bottom_origin.y);
|
|
hash_combine(seed, desc.bottom_origin.z);
|
|
hash_combine(seed, desc.radius);
|
|
hash_combine(seed, desc.height);
|
|
hash_combine(seed, desc.offset.x);
|
|
hash_combine(seed, desc.offset.y);
|
|
hash_combine(seed, desc.offset.z);
|
|
return seed;
|
|
}
|
|
};
|
|
|
|
template <>
|
|
struct eq_compare<cylinder_descriptor_t> {
|
|
bool operator()(const cylinder_descriptor_t& lhs, const cylinder_descriptor_t& rhs) const
|
|
{
|
|
constexpr double eps = 1e-12;
|
|
return std::abs(lhs.radius - rhs.radius) < eps && std::abs(lhs.height - rhs.height) < eps;
|
|
}
|
|
};
|
|
|
|
template <>
|
|
struct hasher<extrude_polyline_descriptor_t> {
|
|
size_t operator()(const extrude_polyline_descriptor_t& desc) const
|
|
{
|
|
size_t h = 0;
|
|
|
|
hash_combine(h, desc.profile_number);
|
|
hash_combine(h, desc.axis.point_number);
|
|
hash_combine(h, desc.axis.bulge_number);
|
|
hash_combine(h, static_cast<int>(desc.axis.is_close));
|
|
|
|
if (desc.profiles && desc.profile_number > 0) {
|
|
const auto& p = desc.profiles[0];
|
|
hash_combine(h, p.point_number);
|
|
hash_combine(h, p.bulge_number);
|
|
hash_combine(h, static_cast<int>(p.is_close));
|
|
|
|
// 哈希所有点的坐标
|
|
for (uint32_t i = 0; i < p.point_number; ++i) {
|
|
hash_combine(h, p.points[i].x);
|
|
hash_combine(h, p.points[i].y);
|
|
hash_combine(h, p.points[i].z);
|
|
}
|
|
}
|
|
// 哈希 axis 数据
|
|
for (uint32_t i = 0; i < desc.axis.point_number; ++i) {
|
|
hash_combine(h, desc.axis.points[i].x);
|
|
hash_combine(h, desc.axis.points[i].y);
|
|
hash_combine(h, desc.axis.points[i].z);
|
|
}
|
|
|
|
return h;
|
|
}
|
|
};
|
|
|
|
// extrude_polyline_descriptor_t 的相等比较
|
|
template <>
|
|
struct eq_compare<extrude_polyline_descriptor_t> {
|
|
bool operator()(const extrude_polyline_descriptor_t& lhs, const extrude_polyline_descriptor_t& rhs) const
|
|
{
|
|
// 比较指针地址
|
|
if (lhs.profiles != rhs.profiles) return false;
|
|
if (lhs.axis.points != rhs.axis.points) return false;
|
|
if (lhs.axis.bulges != rhs.axis.bulges) return false;
|
|
|
|
// 比较基本字段
|
|
if (lhs.profile_number != rhs.profile_number) return false;
|
|
if (lhs.axis.point_number != rhs.axis.point_number) return false;
|
|
if (lhs.axis.bulge_number != rhs.axis.bulge_number) return false;
|
|
if (lhs.axis.is_close != rhs.axis.is_close) return false;
|
|
|
|
return true;
|
|
}
|
|
};
|
|
|
|
// extrude_helixline_descriptor_t 的哈希
|
|
template <>
|
|
struct hasher<extrude_helixline_descriptor_t> {
|
|
size_t operator()(const extrude_helixline_descriptor_t& desc) const
|
|
{
|
|
size_t h = 0;
|
|
|
|
hash_combine(h, desc.profile_number);
|
|
|
|
// 哈希所有 profiles
|
|
for (uint32_t profile_idx = 0; profile_idx < desc.profile_number; ++profile_idx) {
|
|
if (!desc.profiles) break;
|
|
|
|
const auto& profile = desc.profiles[profile_idx];
|
|
hash_combine(h, profile.point_number);
|
|
hash_combine(h, profile.bulge_number);
|
|
hash_combine(h, profile.is_close);
|
|
|
|
// reference_normal
|
|
hash_combine(h, profile.reference_normal.x);
|
|
hash_combine(h, profile.reference_normal.y);
|
|
hash_combine(h, profile.reference_normal.z);
|
|
|
|
for (uint32_t i = 0; i < profile.point_number; ++i) {
|
|
hash_combine(h, profile.points[i].x);
|
|
hash_combine(h, profile.points[i].y);
|
|
hash_combine(h, profile.points[i].z);
|
|
}
|
|
|
|
for (uint32_t i = 0; i < profile.bulge_number; ++i) { hash_combine(h, profile.bulges[i]); }
|
|
}
|
|
|
|
// 哈希 helixline axis(完整字段)
|
|
hash_combine(h, desc.axis.axis_start.x);
|
|
hash_combine(h, desc.axis.axis_start.y);
|
|
hash_combine(h, desc.axis.axis_start.z);
|
|
hash_combine(h, desc.axis.axis_end.x);
|
|
hash_combine(h, desc.axis.axis_end.y);
|
|
hash_combine(h, desc.axis.axis_end.z);
|
|
hash_combine(h, desc.axis.radius);
|
|
hash_combine(h, desc.axis.advance_per_round);
|
|
|
|
// start_direction
|
|
hash_combine(h, desc.axis.start_direction.x);
|
|
hash_combine(h, desc.axis.start_direction.y);
|
|
hash_combine(h, desc.axis.start_direction.z);
|
|
|
|
hash_combine(h, desc.axis.is_righthanded);
|
|
|
|
return h;
|
|
}
|
|
};
|
|
|
|
// extrude_helixline_descriptor_t 的相等比较
|
|
template <>
|
|
struct eq_compare<extrude_helixline_descriptor_t> {
|
|
bool operator()(const extrude_helixline_descriptor_t& lhs, const extrude_helixline_descriptor_t& rhs) const
|
|
{
|
|
constexpr double eps = 1e-12;
|
|
|
|
if (lhs.profile_number != rhs.profile_number) return false;
|
|
|
|
//
|
|
// 比较所有 profiles
|
|
for (uint32_t profile_idx = 0; profile_idx < lhs.profile_number; ++profile_idx) {
|
|
const auto& lp = lhs.profiles[profile_idx];
|
|
const auto& rp = rhs.profiles[profile_idx];
|
|
|
|
if (lp.point_number != rp.point_number) return false;
|
|
if (lp.bulge_number != rp.bulge_number) return false;
|
|
if (lp.is_close != rp.is_close) return false;
|
|
|
|
// reference_normal
|
|
if (std::abs(lp.reference_normal.x - rp.reference_normal.x) > eps) return false;
|
|
if (std::abs(lp.reference_normal.y - rp.reference_normal.y) > eps) return false;
|
|
if (std::abs(lp.reference_normal.z - rp.reference_normal.z) > eps) return false;
|
|
|
|
for (uint32_t i = 0; i < lp.point_number; ++i) {
|
|
if (std::abs(lp.points[i].x - rp.points[i].x) > eps) return false;
|
|
if (std::abs(lp.points[i].y - rp.points[i].y) > eps) return false;
|
|
if (std::abs(lp.points[i].z - rp.points[i].z) > eps) return false;
|
|
}
|
|
|
|
for (uint32_t i = 0; i < lp.bulge_number; ++i) {
|
|
if (std::abs(lp.bulges[i] - rp.bulges[i]) > eps) return false;
|
|
}
|
|
}
|
|
|
|
// 比较 helixline axis(完整字段)
|
|
if (std::abs(lhs.axis.axis_start.x - rhs.axis.axis_start.x) > eps) return false;
|
|
if (std::abs(lhs.axis.axis_start.y - rhs.axis.axis_start.y) > eps) return false;
|
|
if (std::abs(lhs.axis.axis_start.z - rhs.axis.axis_start.z) > eps) return false;
|
|
if (std::abs(lhs.axis.axis_end.x - rhs.axis.axis_end.x) > eps) return false;
|
|
if (std::abs(lhs.axis.axis_end.y - rhs.axis.axis_end.y) > eps) return false;
|
|
if (std::abs(lhs.axis.axis_end.z - rhs.axis.axis_end.z) > eps) return false;
|
|
if (std::abs(lhs.axis.radius - rhs.axis.radius) > eps) return false;
|
|
if (std::abs(lhs.axis.advance_per_round - rhs.axis.advance_per_round) > eps) return false;
|
|
|
|
// start_direction
|
|
if (std::abs(lhs.axis.start_direction.x - rhs.axis.start_direction.x) > eps) return false;
|
|
if (std::abs(lhs.axis.start_direction.y - rhs.axis.start_direction.y) > eps) return false;
|
|
if (std::abs(lhs.axis.start_direction.z - rhs.axis.start_direction.z) > eps) return false;
|
|
|
|
if (lhs.axis.is_righthanded != rhs.axis.is_righthanded) return false;
|
|
|
|
return true;
|
|
}
|
|
};
|
|
|
|
} // namespace descriptor_defaults
|