Temporary repository used to save branch code
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

#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