From 8883f8efa76cccb97794a4facf36b9923034c6af Mon Sep 17 00:00:00 2001 From: Artem Zhidkov Date: Fri, 29 May 2020 14:24:17 +0300 Subject: [PATCH] Issue #19019: python dump not loadable Geometrical selection: search a face, using projection of a point to it. It was done, because for some reasons, parametric boundaries of a face may float from time to time. --- src/GeomAPI/GeomAPI_Vertex.cpp | 18 ++++++++++++++---- src/GeomAPI/GeomAPI_Vertex.h | 4 ++++ src/ModelGeomAlgo/ModelGeomAlgo_Shape.cpp | 22 +++++++++++++++++++++- 3 files changed, 39 insertions(+), 5 deletions(-) diff --git a/src/GeomAPI/GeomAPI_Vertex.cpp b/src/GeomAPI/GeomAPI_Vertex.cpp index 042b9d5c3..43a43e7eb 100644 --- a/src/GeomAPI/GeomAPI_Vertex.cpp +++ b/src/GeomAPI/GeomAPI_Vertex.cpp @@ -29,6 +29,14 @@ #include #include +static TopoDS_Shape* buildVertex(const gp_Pnt& thePoint) +{ + TopoDS_Vertex aVertex; + BRep_Builder aBuilder; + aBuilder.MakeVertex(aVertex, thePoint, Precision::Confusion()); + return new TopoDS_Shape(aVertex); +} + GeomAPI_Vertex::GeomAPI_Vertex() : GeomAPI_Shape() { @@ -41,12 +49,14 @@ GeomAPI_Vertex::GeomAPI_Vertex(const std::shared_ptr& theShape) } } +GeomAPI_Vertex::GeomAPI_Vertex(const std::shared_ptr& thePoint) +{ + setImpl(buildVertex(thePoint->impl())); +} + GeomAPI_Vertex::GeomAPI_Vertex(double theX, double theY, double theZ) { - TopoDS_Vertex aVertex; - BRep_Builder aBuilder; - aBuilder.MakeVertex(aVertex, gp_Pnt(theX, theY, theZ), Precision::Confusion()); - setImpl(new TopoDS_Shape(aVertex)); + setImpl(buildVertex(gp_Pnt(theX, theY, theZ))); } std::shared_ptr GeomAPI_Vertex::point() diff --git a/src/GeomAPI/GeomAPI_Vertex.h b/src/GeomAPI/GeomAPI_Vertex.h index cded80618..53aed1f91 100644 --- a/src/GeomAPI/GeomAPI_Vertex.h +++ b/src/GeomAPI/GeomAPI_Vertex.h @@ -38,6 +38,10 @@ public: GEOMAPI_EXPORT GeomAPI_Vertex(const std::shared_ptr& theShape); + /// Creation of vertex by the given point. + GEOMAPI_EXPORT + GeomAPI_Vertex(const std::shared_ptr& thePoint); + /// Creation of vertex by 3d coordinates. GEOMAPI_EXPORT GeomAPI_Vertex(double theX, double theY, double theZ); diff --git a/src/ModelGeomAlgo/ModelGeomAlgo_Shape.cpp b/src/ModelGeomAlgo/ModelGeomAlgo_Shape.cpp index 5de56ada2..b92bf677b 100644 --- a/src/ModelGeomAlgo/ModelGeomAlgo_Shape.cpp +++ b/src/ModelGeomAlgo/ModelGeomAlgo_Shape.cpp @@ -33,6 +33,8 @@ #include #include +#include + #ifdef WIN32 #pragma warning(disable : 4996) // for sprintf @@ -78,7 +80,25 @@ namespace ModelGeomAlgo_Shape for (std::list::const_iterator aSubIt = aSubs.begin(); aSubIt != aSubs.end(); ++aSubIt) { GeomPointPtr aMiddlePoint = (*aSubIt)->middlePoint(); - if (aMiddlePoint && aMiddlePoint->distance(thePoint) < theTolerance) + if (!aMiddlePoint) + continue; + + double aDistance = aMiddlePoint->distance(thePoint); + bool isFound = aDistance < theTolerance; + // issue #19019: special workaround for faces, because if the face contains B-spline contour, + // the middle point is calculated with respect to its poles, but not a curve itself. + // Thus is some operations (like BOP) the curve may have different number of poles + // from time to time, as a result, the face parametric boundaries are floating + // as well as the middle point. + // The workaround is to find a distance from the picking point to the face, if the distance + // between the picking point and the middle point on the face is small to some extend. + static const double THE_THRESHOLD = 100.; + if (!isFound && aDistance < THE_THRESHOLD * theTolerance && (*aSubIt)->isFace()) { + GeomVertexPtr aVertex(new GeomAPI_Vertex(thePoint)); + aDistance = GeomAlgoAPI_ShapeTools::minimalDistance(aVertex, *aSubIt); + isFound = aDistance < theTolerance; + } + if (isFound) aFoundSubs.push_back(*aSubIt); } return aFoundSubs; -- 2.39.2