Measuring - Some refactoring

This commit is contained in:
enricoturri1966 2022-09-30 14:13:17 +02:00
parent 0ef8115564
commit 6be56413f6
3 changed files with 25 additions and 21 deletions

View File

@ -250,7 +250,7 @@ void MeasuringImpl::extract_features()
// Add the circle and remember indices into borders. // Add the circle and remember indices into borders.
const auto& [center, radius] = get_center_and_radius(border, start_idx, i, trafo); const auto& [center, radius] = get_center_and_radius(border, start_idx, i, trafo);
circles_idxs.emplace_back(start_idx, i); circles_idxs.emplace_back(start_idx, i);
circles.emplace_back(SurfaceFeature(SurfaceFeatureType::Circle, center, plane.normal, std::optional<Vec3d>(), radius)); circles.emplace_back(SurfaceFeature(SurfaceFeatureType::Circle, center, plane.normal, std::nullopt, radius));
circle = false; circle = false;
} }
} }
@ -269,7 +269,7 @@ void MeasuringImpl::extract_features()
const Vec3d center = std::get<0>(circles[i].get_circle()); const Vec3d center = std::get<0>(circles[i].get_circle());
for (int j=(int)circles_idxs[i].first + 1; j<=(int)circles_idxs[i].second; ++j) for (int j=(int)circles_idxs[i].first + 1; j<=(int)circles_idxs[i].second; ++j)
plane.surface_features.emplace_back(SurfaceFeature(SurfaceFeatureType::Edge, plane.surface_features.emplace_back(SurfaceFeature(SurfaceFeatureType::Edge,
border[j-1], border[j], std::make_optional(center), 0.)); border[j - 1], border[j], std::make_optional(center)));
} else { } else {
// This will be handled just like a regular edge. // This will be handled just like a regular edge.
circles_idxs.erase(circles_idxs.begin() + i); circles_idxs.erase(circles_idxs.begin() + i);
@ -288,8 +288,8 @@ void MeasuringImpl::extract_features()
for (int i=1; i<int(border.size()); ++i) { for (int i=1; i<int(border.size()); ++i) {
if (cidx < (int)circles_idxs.size() && i > (int)circles_idxs[cidx].first) if (cidx < (int)circles_idxs.size() && i > (int)circles_idxs[cidx].first)
i = circles_idxs[cidx++].second; i = circles_idxs[cidx++].second;
else plane.surface_features.emplace_back(SurfaceFeature( else
SurfaceFeatureType::Edge, border[i-1], border[i], std::optional<Vec3d>(), 0.)); plane.surface_features.emplace_back(SurfaceFeature(SurfaceFeatureType::Edge, border[i - 1], border[i]));
} }
// FIXME Throw away / do not create edges which are parts of circles or // FIXME Throw away / do not create edges which are parts of circles or
@ -307,7 +307,7 @@ void MeasuringImpl::extract_features()
// The last surface feature is the plane itself. // The last surface feature is the plane itself.
plane.surface_features.emplace_back(SurfaceFeature(SurfaceFeatureType::Plane, plane.surface_features.emplace_back(SurfaceFeature(SurfaceFeatureType::Plane,
plane.normal, plane.borders.front().front(), std::optional<Vec3d>(), i + 0.0001)); plane.normal, plane.borders.front().front(), std::nullopt, i + 0.0001));
plane.borders.clear(); plane.borders.clear();
plane.borders.shrink_to_fit(); plane.borders.shrink_to_fit();
@ -433,13 +433,12 @@ std::vector<std::vector<int>> Measuring::get_planes_triangle_indices() const
static AngleAndPoints angle_edge_edge(const std::pair<Vec3d, Vec3d>& e1, const std::pair<Vec3d, Vec3d>& e2) static AngleAndPoints angle_edge_edge(const std::pair<Vec3d, Vec3d>& e1, const std::pair<Vec3d, Vec3d>& e2)
{ {
Vec3d e1_unit = (e1.second - e1.first).normalized(); if (are_parallel(e1, e2))
Vec3d e2_unit = (e2.second - e2.first).normalized();
const double dot = e1_unit.dot(e2_unit);
// are edges parallel ?
if (std::abs(std::abs(dot) - 1.0) < EPSILON)
return AngleAndPoints(0.0, e1.first, Vec3d::UnitX(), Vec3d::UnitX(), 0., true); return AngleAndPoints(0.0, e1.first, Vec3d::UnitX(), Vec3d::UnitX(), 0., true);
Vec3d e1_unit = edge_direction(e1.first, e1.second);
Vec3d e2_unit = edge_direction(e2.first, e2.second);
// project edges on the plane defined by them // project edges on the plane defined by them
Vec3d normal = e1_unit.cross(e2_unit).normalized(); Vec3d normal = e1_unit.cross(e2_unit).normalized();
const Eigen::Hyperplane<double, 3> plane(normal, e1.first); const Eigen::Hyperplane<double, 3> plane(normal, e1.first);
@ -562,7 +561,7 @@ MeasurementResult get_measurement(const SurfaceFeature& a, const SurfaceFeature&
std::vector<DistAndPoints> distances; std::vector<DistAndPoints> distances;
auto add_point_edge_distance = [&distances](const Vec3d& v, const std::pair<Vec3d, Vec3d>& e) { auto add_point_edge_distance = [&distances](const Vec3d& v, const std::pair<Vec3d, Vec3d>& e) {
const MeasurementResult res = get_measurement(SurfaceFeature(v), SurfaceFeature(SurfaceFeatureType::Edge, e.first, e.second, std::optional<Vec3d>(), 0.)); const MeasurementResult res = get_measurement(SurfaceFeature(v), SurfaceFeature(SurfaceFeatureType::Edge, e.first, e.second));
double distance = res.distance_strict->dist; double distance = res.distance_strict->dist;
Vec3d v2 = res.distance_strict->to; Vec3d v2 = res.distance_strict->to;

View File

@ -25,8 +25,8 @@ enum class SurfaceFeatureType : int {
class SurfaceFeature { class SurfaceFeature {
public: public:
SurfaceFeature(SurfaceFeatureType type, const Vec3d& pt1, const Vec3d& pt2, std::optional<Vec3d> pt3, double value) SurfaceFeature(SurfaceFeatureType type, const Vec3d& pt1, const Vec3d& pt2, std::optional<Vec3d> pt3 = std::nullopt, double value = 0.0)
: m_type{type}, m_pt1{pt1}, m_pt2{pt2}, m_pt3{pt3}, m_value{value} {} : m_type{ type }, m_pt1{ pt1 }, m_pt2{ pt2 }, m_pt3{ pt3 }, m_value{ value } {}
explicit SurfaceFeature(const Vec3d& pt) explicit SurfaceFeature(const Vec3d& pt)
: m_type{SurfaceFeatureType::Point}, m_pt1{pt} {} : m_type{SurfaceFeatureType::Point}, m_pt1{pt} {}
@ -157,6 +157,9 @@ inline Vec3d plane_normal(const SurfaceFeature& plane) {
inline bool are_parallel(const Vec3d& v1, const Vec3d& v2) { return std::abs(std::abs(v1.dot(v2)) - 1.0) < EPSILON; } inline bool are_parallel(const Vec3d& v1, const Vec3d& v2) { return std::abs(std::abs(v1.dot(v2)) - 1.0) < EPSILON; }
inline bool are_perpendicular(const Vec3d& v1, const Vec3d& v2) { return std::abs(v1.dot(v2)) < EPSILON; } inline bool are_perpendicular(const Vec3d& v1, const Vec3d& v2) { return std::abs(v1.dot(v2)) < EPSILON; }
inline bool are_parallel(const std::pair<Vec3d, Vec3d>& e1, const std::pair<Vec3d, Vec3d>& e2) {
return are_parallel(e1.second - e1.first, e2.second - e2.first);
}
inline bool are_parallel(const SurfaceFeature& f1, const SurfaceFeature& f2) { inline bool are_parallel(const SurfaceFeature& f1, const SurfaceFeature& f2) {
if (f1.get_type() == SurfaceFeatureType::Edge && f2.get_type() == SurfaceFeatureType::Edge) if (f1.get_type() == SurfaceFeatureType::Edge && f2.get_type() == SurfaceFeatureType::Edge)
return are_parallel(edge_direction(f1), edge_direction(f2)); return are_parallel(edge_direction(f1), edge_direction(f2));

View File

@ -887,8 +887,6 @@ void GLGizmoMeasure::render_dimensioning()
double draw_radius = force_radius ? *force_radius : radius; double draw_radius = force_radius ? *force_radius : radius;
const Vec3d normal = e1_unit.cross(e2_unit).normalized();
if (!m_dimensioning.arc.is_initialized()) { if (!m_dimensioning.arc.is_initialized()) {
const unsigned int resolution = std::max<unsigned int>(2, 64 * angle / double(PI)); const unsigned int resolution = std::max<unsigned int>(2, 64 * angle / double(PI));
GLModel::Geometry init_data; GLModel::Geometry init_data;
@ -898,6 +896,7 @@ void GLGizmoMeasure::render_dimensioning()
init_data.reserve_indices(resolution + 1); init_data.reserve_indices(resolution + 1);
// vertices + indices // vertices + indices
const Vec3d normal = e1_unit.cross(e2_unit).normalized();
const double step = angle / double(resolution); const double step = angle / double(resolution);
for (unsigned int i = 0; i <= resolution; ++i) { for (unsigned int i = 0; i <= resolution; ++i) {
const double a = step * double(i); const double a = step * double(i);
@ -943,16 +942,19 @@ void GLGizmoMeasure::render_dimensioning()
auto arc_edge_plane = [this, arc_edge_edge](const Measure::SurfaceFeature& f1, const Measure::SurfaceFeature& f2) { auto arc_edge_plane = [this, arc_edge_edge](const Measure::SurfaceFeature& f1, const Measure::SurfaceFeature& f2) {
assert(f1.get_type() == Measure::SurfaceFeatureType::Edge && f2.get_type() == Measure::SurfaceFeatureType::Plane); assert(f1.get_type() == Measure::SurfaceFeatureType::Edge && f2.get_type() == Measure::SurfaceFeatureType::Plane);
std::pair<Vec3d, Vec3d> e = f1.get_edge();
const auto [idx, normal, origin] = f2.get_plane();
if (Measure::are_parallel(f1, f2) || Measure::are_perpendicular(f1, f2)) if (Measure::are_parallel(f1, f2) || Measure::are_perpendicular(f1, f2))
return; return;
const std::pair<Vec3d, Vec3d> e = f1.get_edge();
const auto [idx, normal, origin] = f2.get_plane();
// ensure the edge is pointing away from the intersection
// 1st calculate instersection between edge and plane
const Eigen::Hyperplane<double, 3> plane(normal, origin); const Eigen::Hyperplane<double, 3> plane(normal, origin);
const Eigen::ParametrizedLine<double, 3> line = Eigen::ParametrizedLine<double, 3>::Through(e.first, e.second); const Eigen::ParametrizedLine<double, 3> line = Eigen::ParametrizedLine<double, 3>::Through(e.first, e.second);
const Vec3d inters = line.intersectionPoint(plane); const Vec3d inters = line.intersectionPoint(plane);
// ensure the edge is pointing away from the intersection // then verify edge direction and revert it, if needed
std::pair<Vec3d, Vec3d> ecopy = e; std::pair<Vec3d, Vec3d> ecopy = e;
if ((ecopy.first - inters).squaredNorm() > (ecopy.second - inters).squaredNorm()) if ((ecopy.first - inters).squaredNorm() > (ecopy.second - inters).squaredNorm())
std::swap(ecopy.first, ecopy.second); std::swap(ecopy.first, ecopy.second);
@ -971,9 +973,9 @@ void GLGizmoMeasure::render_dimensioning()
const Vec3d e1e2copy_mid = 0.5 * (ecopy.second + ecopy.first); const Vec3d e1e2copy_mid = 0.5 * (ecopy.second + ecopy.first);
const double radius = (inters - e1e2copy_mid).norm(); const double radius = (inters - e1e2copy_mid).norm();
arc_edge_edge(Measure::SurfaceFeature(Measure::SurfaceFeatureType::Edge, ecopy.second, ecopy.first, std::optional<Vec3d>(), 0.), arc_edge_edge(Measure::SurfaceFeature(Measure::SurfaceFeatureType::Edge, ecopy.first, ecopy.second),
Measure::SurfaceFeature(Measure::SurfaceFeatureType::Edge, edge_on_plane.second, edge_on_plane.first, std::optional<Vec3d>(), 0.), Measure::SurfaceFeature(Measure::SurfaceFeatureType::Edge, edge_on_plane.first, edge_on_plane.second),
&radius); &radius);
}; };