From 43fa188aa74a3f03a59beb6be8235a32f1b8fe84 Mon Sep 17 00:00:00 2001 From: Dtouch Date: Fri, 3 Jan 2025 01:32:51 +0800 Subject: [PATCH] sign for distance --- .../interface/internal_primitive_desc.hpp | 5 ++++- primitive_process/interface/primitive_descriptor.h | 1 + primitive_process/src/extrude_helixline.cpp | 5 ++++- primitive_process/src/extrude_polyline.cpp | 8 ++++++-- primitive_process/src/helixline.cpp | 7 +++++++ primitive_process/src/polyline.cpp | 10 ++++++---- 6 files changed, 28 insertions(+), 8 deletions(-) diff --git a/primitive_process/interface/internal_primitive_desc.hpp b/primitive_process/interface/internal_primitive_desc.hpp index 7d1d54b..cdac6a4 100644 --- a/primitive_process/interface/internal_primitive_desc.hpp +++ b/primitive_process/interface/internal_primitive_desc.hpp @@ -204,13 +204,15 @@ struct polyline { const Eigen::Ref&) const; // return type: true for outside - [[nodiscard]] bool pmc(const Eigen::Ref&, const line_closest_param_t&) const; + [[nodiscard]] bool pmc(const Eigen::Ref&, const line_closest_param_t&) const; + [[nodiscard]] bool isEnd(const double t) const; }; struct helixline { double radius{}; double total_theta{}; double height{}; + bool is_clockwise{}; // CAUTION: here returned aabb is in helixline's local space helixline(const helixline_descriptor_t&, Eigen::Transform&, aabb_t<>&); @@ -220,6 +222,7 @@ struct helixline { [[nodiscard]] Eigen::Vector3d calculate_normal(double) const; // CAUTION: make sure the input point is in the local space of the helixline [[nodiscard]] line_closest_param_t calculate_closest_param(const Eigen::Ref&) const; + [[nodiscard]] bool isEnd(const double t) const; }; struct PE_API extrude_polyline { diff --git a/primitive_process/interface/primitive_descriptor.h b/primitive_process/interface/primitive_descriptor.h index 42ca5d3..484d978 100644 --- a/primitive_process/interface/primitive_descriptor.h +++ b/primitive_process/interface/primitive_descriptor.h @@ -87,6 +87,7 @@ typedef struct { double radius; // The radius of the helix line double advance_per_round; // he advance per round of the helix line raw_vector3d_t start_direction; // The direction from axisStart to start of the helix line + bool is_clockwise; } helixline_descriptor_t; // Note : In profiles, The first polyline is outer boundary, and the ohters is internal holes diff --git a/primitive_process/src/extrude_helixline.cpp b/primitive_process/src/extrude_helixline.cpp index 1094956..ddfcc14 100644 --- a/primitive_process/src/extrude_helixline.cpp +++ b/primitive_process/src/extrude_helixline.cpp @@ -66,7 +66,10 @@ static inline process_return_type_t evaluate(const extrude_helixline // TODO: add support for non-parallel (ray vs. profile plane) case // for now just assume that profile plane is parallel to axis auto [profile_closest_param, dist] = desc.profile.calculate_closest_param((inv_TBN * local_p).topRows<3>()); - dist *= desc.profile.pmc((inv_TBN * local_p).topRows<3>(), profile_closest_param); + if (axis_closest_param.is_peak_value) { + // if !is_peak_value, the point is two sides away, and pmc is always true + dist *= desc.profile.pmc((inv_TBN * local_p).topRows<2>(), profile_closest_param); + } // transform closest point to world space // the distance should be unchanged during transformation, since no scaling is involved diff --git a/primitive_process/src/extrude_polyline.cpp b/primitive_process/src/extrude_polyline.cpp index d59b2d7..ec368e0 100644 --- a/primitive_process/src/extrude_polyline.cpp +++ b/primitive_process/src/extrude_polyline.cpp @@ -66,14 +66,18 @@ static inline process_return_type_t evaluate(const extrude_polyline { const auto world_to_axis = inversed_affine_transform(desc.axis_to_world); const auto local_p = world_to_axis * Eigen::Vector4d{point[0], point[1], point[2], 1}; - const auto [axis_closest_param, _] = desc.axis.calculate_closest_param(local_p.topRows<3>()); + const auto [axis_closest_param, axis_closest_t] = desc.axis.calculate_closest_param(local_p.topRows<3>()); const auto TBN = get_local_TBN(desc.axis, local_p, axis_closest_param.point, axis_closest_param.t); const auto inv_TBN = inversed_affine_transform(TBN); // TODO: add support for non-parallel (ray vs. profile plane) case // for now just assume that profile plane is parallel to axis auto [profile_closest_param, dist] = desc.profile.calculate_closest_param((inv_TBN * local_p).topRows<3>()); - dist *= desc.profile.pmc((inv_TBN * local_p).topRows<3>(), profile_closest_param); + if (!desc.axis.isEnd(axis_closest_t) || !axis_closest_param.is_peak_value) { + // when the point is two sides away, and pmc is always true + dist *= desc.profile.pmc((inv_TBN * local_p).topRows<2>(), profile_closest_param); + } + // transform closest point to world space // the distance should be unchanged during transformation, since no scaling is involved diff --git a/primitive_process/src/helixline.cpp b/primitive_process/src/helixline.cpp index d024527..326f102 100644 --- a/primitive_process/src/helixline.cpp +++ b/primitive_process/src/helixline.cpp @@ -14,6 +14,7 @@ helixline::helixline(const helixline_descriptor_t &desc, this->radius = desc.radius; this->height = (topper - origin).norm(); this->total_theta = this->height / desc.advance_per_round * TWO_PI; + this->is_clockwise = desc.is_clockwise; auto &matrix_handle = axis_to_world.matrix(); vec3d_conversion(desc.start_direction, matrix_handle.col(0)); @@ -38,6 +39,7 @@ helixline::helixline(helixline_descriptor_t &&desc, this->radius = std::move(desc.radius); this->height = (topper - origin).norm(); this->total_theta = this->height / std::move(desc.advance_per_round) * TWO_PI; + this->is_clockwise = std::move(desc.is_clockwise); auto &matrix_handle = axis_to_world.matrix(); vec3d_conversion(std::move(desc.start_direction), matrix_handle.col(0)); @@ -180,4 +182,9 @@ helixline::helixline(helixline_descriptor_t &&desc, peak_value_param.is_peak_value }; } + +[[nodiscard]] bool helixline::isEnd(const double t) const +{ + return t >= 1 - EPSILON || t < EPSILON; +} } // namespace internal \ No newline at end of file diff --git a/primitive_process/src/polyline.cpp b/primitive_process/src/polyline.cpp index 0ce3281..73f4231 100644 --- a/primitive_process/src/polyline.cpp +++ b/primitive_process/src/polyline.cpp @@ -405,14 +405,16 @@ void polyline::build_as_profile(polyline_descriptor_t &&desc, } } -[[nodiscard]] bool polyline::pmc(const Eigen::Ref&p, const line_closest_param_t& closest_param) const { +[[nodiscard]] bool polyline::pmc(const Eigen::Ref&p, const line_closest_param_t& closest_param) const { if (closest_param.is_peak_value) { - return (p - closest_param.point).dot(this->calculate_normal(closest_param.t)) < 0; + return (p - closest_param.point.topRows<2>()).dot(this->calculate_normal(closest_param.t)) < 0; } // the closest point is the vertex of the line // todo: may not be robust for rare cases - return (p - closest_param.point).dot(this->calculate_normal(closest_param.t)) < 0; + return (p - closest_param.point.topRows<2>()).dot(this->calculate_normal(closest_param.t)) < 0; } - +[[nodiscard]] bool polyline::isEnd(const double t) const { + return t >= thetas.size() - EPSILON || t < EPSILON; +} } // namespace internal \ No newline at end of file