From 4e1023cda1eb0935fca18249c085ed59179e6e57 Mon Sep 17 00:00:00 2001 From: wmayer Date: Wed, 23 Oct 2024 11:59:44 +0200 Subject: [PATCH] Measure: When measuring the distance between circles then use the center points as reference See forum: https://forum.freecad.org/viewtopic.php?t=91570 --- src/Mod/Measure/App/MeasureDistance.cpp | 101 ++++++++++++++++++++---- src/Mod/Measure/App/MeasureDistance.h | 10 +++ 2 files changed, 95 insertions(+), 16 deletions(-) diff --git a/src/Mod/Measure/App/MeasureDistance.cpp b/src/Mod/Measure/App/MeasureDistance.cpp index e2ac25b126..aa748856df 100644 --- a/src/Mod/Measure/App/MeasureDistance.cpp +++ b/src/Mod/Measure/App/MeasureDistance.cpp @@ -27,7 +27,13 @@ #include #include #include +#include +#include #include +#include +#include +#include +#include #include "MeasureDistance.h" @@ -178,6 +184,44 @@ bool MeasureDistance::getShape(App::PropertyLinkSub* prop, TopoDS_Shape& rShape) return true; } +bool MeasureDistance::distanceCircleCircle(const TopoDS_Shape& shape1, const TopoDS_Shape& shape2) +{ + auto circle1 = asCircle(shape1); + auto circle2 = asCircle(shape2); + if (!circle1.IsNull() && !circle2.IsNull()) { + const gp_Pnt p1 = circle1->Location(); + const gp_Pnt p2 = circle2->Location(); + setValues(p1, p2); + return true; + } + + return false; +} + +void MeasureDistance::distanceGeneric(const TopoDS_Shape& shape1, const TopoDS_Shape& shape2) +{ + // Calculate the extrema + BRepExtrema_DistShapeShape measure(shape1, shape2); + if (!measure.IsDone() || measure.NbSolution() < 1) { + throw Base::RuntimeError("Could not get extrema"); + } + + const gp_Pnt p1 = measure.PointOnShape1(1); + const gp_Pnt p2 = measure.PointOnShape2(1); + setValues(p1, p2); +} + +void MeasureDistance::setValues(const gp_Pnt& p1, const gp_Pnt& p2) +{ + Position1.setValue(p1.X(), p1.Y(), p1.Z()); + Position2.setValue(p2.X(), p2.Y(), p2.Z()); + + const gp_Pnt delta = p2.XYZ() - p1.XYZ(); + Distance.setValue(p1.Distance(p2)); + DistanceX.setValue(std::fabs(delta.X())); + DistanceY.setValue(std::fabs(delta.Y())); + DistanceZ.setValue(std::fabs(delta.Z())); +} App::DocumentObjectExecReturn* MeasureDistance::execute() { @@ -207,24 +251,11 @@ App::DocumentObjectExecReturn* MeasureDistance::execute() return new App::DocumentObjectExecReturn("Could not get shape"); } - // Calculate the extrema - BRepExtrema_DistShapeShape measure(shape1, shape2); - if (!measure.IsDone() || measure.NbSolution() < 1) { - return new App::DocumentObjectExecReturn("Could not get extrema"); + if (distanceCircleCircle(shape1, shape2)) { + return DocumentObject::StdReturn; } - gp_Pnt p1 = measure.PointOnShape1(1); - Position1.setValue(p1.X(), p1.Y(), p1.Z()); - - gp_Pnt p2 = measure.PointOnShape2(1); - Position2.setValue(p2.X(), p2.Y(), p2.Z()); - - gp_Pnt delta = measure.PointOnShape2(1).XYZ() - measure.PointOnShape1(1).XYZ(); - Distance.setValue(measure.Value()); - DistanceX.setValue(fabs(delta.X())); - DistanceY.setValue(fabs(delta.Y())); - DistanceZ.setValue(fabs(delta.Z())); - + distanceGeneric(shape1, shape2); return DocumentObject::StdReturn; } @@ -240,6 +271,44 @@ void MeasureDistance::onChanged(const App::Property* prop) DocumentObject::onChanged(prop); } +Handle(Geom_Circle) MeasureDistance::asCircle(const TopoDS_Shape& shape) const +{ + if (shape.IsNull()) { + return {}; + } + + if (shape.ShapeType() == TopAbs_EDGE) { + return asCircle(TopoDS::Edge(shape)); + } + + if (shape.ShapeType() == TopAbs_WIRE) { + return asCircle(TopoDS::Wire(shape)); + } + + return {}; +} + +Handle(Geom_Circle) MeasureDistance::asCircle(const TopoDS_Edge& edge) const +{ + Handle(Geom_Circle) circle; + BRepAdaptor_Curve adapt(edge); + if (adapt.GetType() == GeomAbs_Circle) { + circle = new Geom_Circle(adapt.Circle()); + } + + return circle; +} + +Handle(Geom_Circle) MeasureDistance::asCircle(const TopoDS_Wire& wire) const +{ + Handle(Geom_Circle) circle; + BRepAdaptor_CompCurve adapt(wire); + if (adapt.GetType() == GeomAbs_Circle) { + circle = new Geom_Circle(adapt.Circle()); + } + + return circle; +} //! Return the object we are measuring //! used by the viewprovider in determining visibility diff --git a/src/Mod/Measure/App/MeasureDistance.h b/src/Mod/Measure/App/MeasureDistance.h index 299561dd69..732ee7e956 100644 --- a/src/Mod/Measure/App/MeasureDistance.h +++ b/src/Mod/Measure/App/MeasureDistance.h @@ -25,6 +25,7 @@ #include +#include #include #include @@ -35,6 +36,9 @@ #include "MeasureBase.h" +class TopoDS_Edge; +class TopoDS_Wire; + namespace Measure { @@ -99,7 +103,13 @@ public: private: + bool distanceCircleCircle(const TopoDS_Shape& shape1, const TopoDS_Shape& shape2); + void distanceGeneric(const TopoDS_Shape& shape1, const TopoDS_Shape& shape2); + void setValues(const gp_Pnt& p1, const gp_Pnt& p2); void onChanged(const App::Property* prop) override; + Handle(Geom_Circle) asCircle(const TopoDS_Shape& shape) const; + Handle(Geom_Circle) asCircle(const TopoDS_Edge& edge) const; + Handle(Geom_Circle) asCircle(const TopoDS_Wire& wire) const; };