From: azv Date: Thu, 24 Mar 2016 07:20:13 +0000 (+0300) Subject: Correct filtering of the edges placed on the sketch plane (issue #1377) X-Git-Tag: V_2.3.0~372 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=afb03e1eabddd6acf2ff850e8043299426f17293;p=modules%2Fshaper.git Correct filtering of the edges placed on the sketch plane (issue #1377) --- diff --git a/src/GeomAPI/GeomAPI_Edge.cpp b/src/GeomAPI/GeomAPI_Edge.cpp index 2edd787d9..eed617307 100644 --- a/src/GeomAPI/GeomAPI_Edge.cpp +++ b/src/GeomAPI/GeomAPI_Edge.cpp @@ -5,6 +5,7 @@ // Author: Artem ZHIDKOV #include +#include #include #include #include @@ -19,6 +20,7 @@ #include #include #include +#include GeomAPI_Edge::GeomAPI_Edge() : GeomAPI_Shape() @@ -172,3 +174,39 @@ void GeomAPI_Edge::getRange(double& theFirst, double& theLast) const const TopoDS_Shape& aShape = const_cast(this)->impl(); Handle(Geom_Curve) aCurve = BRep_Tool::Curve((const TopoDS_Edge&)aShape, theFirst, theLast); } + +bool GeomAPI_Edge::isInPlane(std::shared_ptr thePlane) const +{ + double aFirst, aLast; + const TopoDS_Shape& aShape = const_cast(this)->impl(); + Handle(Geom_Curve) aCurve = BRep_Tool::Curve((const TopoDS_Edge&)aShape, aFirst, aLast); + + double A, B, C, D; + thePlane->coefficients(A, B, C, D); + gp_Pln aPlane(A, B, C, D); + + bool inPlane = false; + if (aCurve->IsKind(STANDARD_TYPE(Geom_Line))) { + // check start and end points on the plane + gp_Pnt aFirstPnt = aCurve->Value(aFirst); + gp_Pnt aLastPnt = aCurve->Value(aLast); + inPlane = aPlane.SquareDistance(aFirstPnt) < Precision::SquareConfusion() && + aPlane.SquareDistance(aLastPnt) < Precision::SquareConfusion(); + } else if (aCurve->IsKind(STANDARD_TYPE(Geom_Circle))) { + // check the center on the plane and normals are collinear + Handle(Geom_Circle) aCirc = Handle(Geom_Circle)::DownCast(aCurve); + gp_Pnt aCenter = aCirc->Location(); + Standard_Real aDot = aPlane.Axis().Direction().Dot(aCirc->Axis().Direction()); + inPlane = aPlane.SquareDistance(aCenter) < Precision::SquareConfusion() && + Abs(Abs(aDot) - 1.0) < Precision::Confusion(); + } else { + // three points checking + gp_Pnt aFirstPnt = aCurve->Value(aFirst); + gp_Pnt aMidPnt = aCurve->Value((aFirst + aLast) / 2.); + gp_Pnt aLastPnt = aCurve->Value(aLast); + inPlane = aPlane.SquareDistance(aFirstPnt) < Precision::SquareConfusion() && + aPlane.SquareDistance(aMidPnt) < Precision::SquareConfusion() && + aPlane.SquareDistance(aLastPnt) < Precision::SquareConfusion(); + } + return inPlane; +} diff --git a/src/GeomAPI/GeomAPI_Edge.h b/src/GeomAPI/GeomAPI_Edge.h index 4c929aa2a..d0d5ca2e8 100644 --- a/src/GeomAPI/GeomAPI_Edge.h +++ b/src/GeomAPI/GeomAPI_Edge.h @@ -9,6 +9,7 @@ #include +class GeomAPI_Pln; class GeomAPI_Pnt; class GeomAPI_Circ; class GeomAPI_Lin; @@ -64,6 +65,10 @@ public: /// Returns range of parameter on the curve GEOMAPI_EXPORT void getRange(double& theFirst, double& theLast) const; + + /// Returns true, if the edge is fully placed in the specified plane + GEOMAPI_EXPORT + bool isInPlane(const std::shared_ptr thePlane) const; }; #endif diff --git a/src/ModuleBase/ModuleBase_ViewerFilters.cpp b/src/ModuleBase/ModuleBase_ViewerFilters.cpp index 8ee95af0c..f92e3895e 100644 --- a/src/ModuleBase/ModuleBase_ViewerFilters.cpp +++ b/src/ModuleBase/ModuleBase_ViewerFilters.cpp @@ -13,6 +13,8 @@ #include #include +#include + #include #include #include @@ -89,20 +91,13 @@ Standard_Boolean ModuleBase_ShapeInPlaneFilter::IsOk(const Handle(SelectMgr_Enti case TopAbs_VERTEX: { gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(aShape)); - return aPlane.Distance(aPnt) < Precision::Confusion(); + return aPlane.SquareDistance(aPnt) < Precision::SquareConfusion(); } case TopAbs_EDGE: { - TopoDS_Edge aEdge = TopoDS::Edge(aShape); - Standard_Real aFirst, aLast; - Handle(Geom_Curve) aCurve = BRep_Tool::Curve(aEdge, aFirst, aLast); - gp_Pnt aFirstPnt = aCurve->Value(aFirst); - gp_Pnt aMidPnt = aCurve->Value((aFirst + aLast) / 2.); - gp_Pnt aLastPnt = aCurve->Value(aLast); - bool aD1 = aPlane.Distance(aFirstPnt) < Precision::Confusion(); - bool aD2 = aPlane.Distance(aMidPnt) < Precision::Confusion(); - bool aD3 = aPlane.Distance(aLastPnt) < Precision::Confusion(); - return aD1 && aD2 && aD3; + std::shared_ptr anEdge(new GeomAPI_Edge); + anEdge->setImpl(new TopoDS_Shape(aShape)); + return anEdge->isInPlane(myPlane); } default: // The object can be selected in Object browser and contain, for example, compound.