From 312d62cc1878b828f07267a2e3ac03e321f4a4b0 Mon Sep 17 00:00:00 2001 From: wandererfan Date: Mon, 31 Oct 2022 13:41:26 -0400 Subject: [PATCH] [Measurement]support for 3 point angle --- src/Mod/Measure/App/Measurement.cpp | 93 ++++++++++++++--------------- src/Mod/Measure/App/Measurement.h | 7 ++- 2 files changed, 52 insertions(+), 48 deletions(-) diff --git a/src/Mod/Measure/App/Measurement.cpp b/src/Mod/Measure/App/Measurement.cpp index f9fd8fd562..931b8aa311 100644 --- a/src/Mod/Measure/App/Measurement.cpp +++ b/src/Mod/Measure/App/Measurement.cpp @@ -22,16 +22,17 @@ #include "PreCompiled.h" #ifndef _PreComp_ -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #endif #include @@ -106,11 +107,8 @@ MeasureType Measurement::getType() std::vector::const_iterator obj = objects.begin(); std::vector::const_iterator subEl = subElements.begin(); - // - //int dims = -1; MeasureType mode; - // Type of References3D int verts = 0; int edges = 0; int faces = 0; @@ -183,11 +181,7 @@ MeasureType Measurement::getType() mode = PointToEdge; } } else { -// if(edges == 2) { -// mode = EdgeToEdge; -// } else { - mode = Edges; -// } + mode = Edges; } } else if (verts > 0) { mode = Points; @@ -272,8 +266,7 @@ double Measurement::length() const break; } default: { - Base::Console().Error("Measurement::length - curve type: %d not implemented\n"); -// throw Base::ValueError("Measurement - length - Curve type not currently handled"); + throw Base::RuntimeError("Measurement - length - Curve type not currently handled"); } } //end switch } //end for @@ -284,20 +277,18 @@ double Measurement::length() const double Measurement::angle(const Base::Vector3d & /*param*/) const { - double result = 0; - int numRefs = References3D.getSize(); + //TODO: do these references arrive as obj+sub pairs or as a struct of obj + [subs]? + const std::vector &objects = References3D.getValues(); + const std::vector &subElements = References3D.getSubValues(); + int numRefs = objects.size(); if(numRefs == 0) { - Base::Console().Error("Measurement::angle - No 3D references available\n"); + throw Base::RuntimeError("No references available for angle measurement"); } else if (measureType == Invalid) { - Base::Console().Error("Measurement::angle - measureType is Invalid\n"); + throw Base::RuntimeError("MeasureType is Invalid for angle measurement"); } else { if(measureType == Edges) { // Only case that is supported is edge to edge - // TODO: handle 3 pt angle if(numRefs == 2) { - const std::vector &objects = References3D.getValues(); - const std::vector &subElements = References3D.getSubValues(); - TopoDS_Shape shape1 = getShape(objects.at(0), subElements.at(0).c_str()); TopoDS_Shape shape2 = getShape(objects.at(1), subElements.at(1).c_str()); @@ -315,34 +306,45 @@ double Measurement::angle(const Base::Vector3d & /*param*/) const gp_Lin l1 = gp_Lin(pnt1,dir1); gp_Lin l2 = gp_Lin(pnt2,dir2); Standard_Real aRad = l1.Angle(l2); - result = aRad * 180 / M_PI; -// return aRad * 180 / M_PI; + return aRad * 180 / M_PI; } else { - Base::Console().Error("Measurement::angle - Need 2 lines to make angle measure\n"); -// throw Base::ValueError("Objects must both be lines"); + throw Base::RuntimeError("Measurement references must both be lines"); } } else { - Base::Console().Error("Measurement::angle - Can not compute angle. Too many lines referenced\n"); -// throw Base::ValueError("Can not compute angle. Too many References3D"); + throw Base::RuntimeError("Can not compute angle measurement - too many references"); } } else if (measureType == Points) { + //NOTE: we are calculating the 3d angle here, not the projected angle + //ASSUMPTION: the references are in end-apex-end order if(numRefs == 3) { - Base::Console().Error("Measurement::angle - 3 point angle not implemented yet\n"); - //TODO: 3 point angle + TopoDS_Shape shape0 = getShape(objects.at(0), subElements.at(0).c_str()); + TopoDS_Shape shape1 = getShape(objects.at(1), subElements.at(1).c_str()); + TopoDS_Shape shape2 = getShape(objects.at(1), subElements.at(2).c_str()); + if (shape0.ShapeType() != TopAbs_VERTEX || + shape1.ShapeType() != TopAbs_VERTEX || + shape2.ShapeType() != TopAbs_VERTEX) { + throw Base::RuntimeError("Measurement references for 3 point angle are not Vertex"); + } + gp_Pnt gEnd0 = BRep_Tool::Pnt(TopoDS::Vertex(shape0)); + gp_Pnt gApex = BRep_Tool::Pnt(TopoDS::Vertex(shape1)); + gp_Pnt gEnd1 = BRep_Tool::Pnt(TopoDS::Vertex(shape2)); + gp_Dir gDir0 = gp_Dir(gEnd0.XYZ() - gApex.XYZ()); + gp_Dir gDir1 = gp_Dir(gEnd1.XYZ() - gApex.XYZ()); + gp_Lin line0 = gp_Lin(gEnd0, gDir0); + gp_Lin line1 = gp_Lin(gEnd1, gDir1); + double radians = line0.Angle(line1); + return radians * 180 / M_PI; } } } - return result; -// throw Base::ValueError("References3D are not Edges"); + throw Base::RuntimeError("Unexpected error for angle measurement"); } double Measurement::radius() const { - double result = 0.0; int numRefs = References3D.getSize(); if(numRefs == 0) { - Base::Console().Error("Measurement::radius - No 3D references available\n"); -// throw Base::ValueError("Measurement - radius - No References3D provided"); + throw Base::RuntimeError("Measurement - radius - No References3D provided"); } else { if(numRefs == 1 || measureType == Edges) { const std::vector &objects = References3D.getValues(); @@ -353,13 +355,11 @@ double Measurement::radius() const BRepAdaptor_Curve curve(edge); if(curve.GetType() == GeomAbs_Circle) { - result = (double) curve.Circle().Radius(); -// return (double) curve.Circle().Radius(); + return (double) curve.Circle().Radius(); } } } -// throw Base::ValueError("Measurement - radius - Invalid References3D Provided"); - return result; + throw Base::RuntimeError("Measurement - radius - Invalid References3D Provided"); } Base::Vector3d Measurement::delta() const @@ -386,8 +386,7 @@ Base::Vector3d Measurement::delta() const gp_Pnt P1 = BRep_Tool::Pnt(vert1); gp_Pnt P2 = BRep_Tool::Pnt(vert2); gp_XYZ diff = P2.XYZ() - P1.XYZ(); - result = Base::Vector3d(diff.X(), diff.Y(), diff.Z()); -// return Base::Vector3d(diff.X(), diff.Y(), diff.Z()); + return Base::Vector3d(diff.X(), diff.Y(), diff.Z()); } } else if(measureType == PointToEdge || measureType == PointToSurface) { diff --git a/src/Mod/Measure/App/Measurement.h b/src/Mod/Measure/App/Measurement.h index bd191c9919..03f1f03ad3 100644 --- a/src/Mod/Measure/App/Measurement.h +++ b/src/Mod/Measure/App/Measurement.h @@ -23,6 +23,8 @@ #ifndef MEASURE_MEASUREMENT_H #define MEASURE_MEASUREMENT_H +#include + #include #include @@ -69,7 +71,6 @@ public: PyObject *getPyObject() override; virtual unsigned int getMemSize() const; -public: // Methods for distances (edge length, two points, edge and a point double length() const; Base::Vector3d delta() const; //when would client use delta?? @@ -83,8 +84,12 @@ public: // Calculate volumetric/mass properties Base::Vector3d massCenter() const; + static Base::Vector3d toVector3d(const gp_Pnt gp) { return Base::Vector3d(gp.X(), gp.Y(), gp.Z()); } + protected: TopoDS_Shape getShape(App::DocumentObject *obj , const char *subName) const; + +private: MeasureType measureType; Py::SmartPtr PythonObject; };