X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FModelGeomAlgo%2FModelGeomAlgo_Shape.cpp;h=182e0f40d13af7a97cc335f6642d4cad2c3dd340;hb=06e7f5859095193fc7f498bd89a7d28009794f53;hp=207e4f3aa807ce4c1b861cd4f76df85927b0a26c;hpb=6e1a23b124d6316096366543c503a8b5489f2f39;p=modules%2Fshaper.git diff --git a/src/ModelGeomAlgo/ModelGeomAlgo_Shape.cpp b/src/ModelGeomAlgo/ModelGeomAlgo_Shape.cpp index 207e4f3aa..182e0f40d 100644 --- a/src/ModelGeomAlgo/ModelGeomAlgo_Shape.cpp +++ b/src/ModelGeomAlgo/ModelGeomAlgo_Shape.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2019 CEA/DEN, EDF R&D +// Copyright (C) 2014-2023 CEA, EDF // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -33,6 +33,8 @@ #include #include +#include + #ifdef WIN32 #pragma warning(disable : 4996) // for sprintf @@ -78,13 +80,31 @@ 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, in 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; } - // Find circular/elliptical edge, which center/focus coincide with the given point + // Find circular/elliptic edge, which center/focus coincide with the given point static GeomShapePtr findEdgeByCenter(const GeomShapePtr& theBaseShape, const GeomPointPtr& theCenter, const double theTolerance, @@ -98,7 +118,7 @@ namespace ModelGeomAlgo_Shape if (!anEdge) continue; - if (anEdge->isCircle()) { + if (anEdge->isCircle() || anEdge->isArc()) { GeomCirclePtr aCircle = anEdge->circle(); if (aCircle->center()->distance(theCenter) < theTolerance) { theCenterType = (int)ModelAPI_AttributeSelection::CIRCLE_CENTER; @@ -131,15 +151,18 @@ namespace ModelGeomAlgo_Shape aSR.mySubshape = theSubshape; aSR.myCenterType = theCenterType; // compound subshapes from other compounds should be processed as whole results - if (aSR.mySubshape && aSR.mySubshape->shapeType() == GeomAPI_Shape::COMPOUND && - !theResult->shape()->isEqual(theSubshape)) { - ResultBodyPtr aResult = std::dynamic_pointer_cast(theResult); - for (int i = 0; aResult && i < aResult->numberOfSubs(); ++i) { - ResultBodyPtr aSub = aResult->subResult(i); - if (aSub->shape()->isEqual(theSubshape)) { - aSR.myResult = aSub; - aSR.mySubshape = GeomShapePtr(); - break; + if (aSR.mySubshape && aSR.mySubshape->shapeType() <= GeomAPI_Shape::COMPSOLID) { + if (theResult->shape()->isEqual(theSubshape)) + aSR.mySubshape = GeomShapePtr(); + else { + ResultBodyPtr aResult = std::dynamic_pointer_cast(theResult); + for (int i = 0; aResult && i < aResult->numberOfSubs(); ++i) { + ResultBodyPtr aSub = aResult->subResult(i); + if (aSub->shape()->isEqual(theSubshape)) { + aSR.myResult = aSub; + aSR.mySubshape = GeomShapePtr(); + break; + } } } } @@ -193,7 +216,7 @@ namespace ModelGeomAlgo_Shape const GeomAPI_Shape::ShapeType& theShapeType, std::list& theSelected) { - static const double TOLERANCE = 1.e-6; + static const double TOLERANCE = 1.5e-6; theSelected.clear(); @@ -271,10 +294,12 @@ namespace ModelGeomAlgo_Shape } } + bool processSketch = theSelected.empty() || (theSelected.size() == 1 && + theSelected.front().myCenterType != (int)ModelAPI_AttributeSelection::NOT_CENTER); // one more special case: the selected entity is a separated sketch point // or an auxiliary sketch edge; they are not included into the sketch result; // thus, it is necessary to pass through the sketch sub-features and find selected. - if (theSelected.empty() && !aResults.empty() && + if (processSketch && !aResults.empty() && (theShapeType == GeomAPI_Shape::VERTEX || theShapeType == GeomAPI_Shape::EDGE)) { CompositeFeaturePtr aCF = std::dynamic_pointer_cast(theFeature); std::shared_ptr aSketchEdges =