X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FModelGeomAlgo%2FModelGeomAlgo_Shape.cpp;h=ca7809b3906a09014590f8416afec48dec5d93d5;hb=d21a0974f79da3df31bc2ccfd5becafb76e815d8;hp=f93dd9e48c77e706ac7e54085ca0869e6bdf7a20;hpb=7074394f8f08413d885f63be01df6bd5007b868c;p=modules%2Fshaper.git diff --git a/src/ModelGeomAlgo/ModelGeomAlgo_Shape.cpp b/src/ModelGeomAlgo/ModelGeomAlgo_Shape.cpp index f93dd9e48..ca7809b39 100644 --- a/src/ModelGeomAlgo/ModelGeomAlgo_Shape.cpp +++ b/src/ModelGeomAlgo/ModelGeomAlgo_Shape.cpp @@ -24,6 +24,10 @@ #include #include +#include + +#include +#include #ifdef WIN32 @@ -46,4 +50,95 @@ namespace ModelGeomAlgo_Shape theShapeResults.insert(aResult); } } + + // Check the point is within shape's bounding box + static bool isPointWithinBB(const GeomPointPtr& thePoint, + const GeomShapePtr& theShape, + const double theTolerance) + { + double aXMin, aXMax, aYMin, aYMax, aZMin, aZMax; + theShape->computeSize(aXMin, aYMin, aZMin, aXMax, aYMax, aZMax); + return thePoint->x() >= aXMin - theTolerance && thePoint->x() <= aXMax + theTolerance && + thePoint->y() >= aYMin - theTolerance && thePoint->y() <= aYMax + theTolerance && + thePoint->z() >= aZMin - theTolerance && thePoint->z() <= aZMax + theTolerance; + } + + // Select sub-shape of the given type, which contains the given point + static GeomShapePtr findSubShape(const GeomShapePtr& theShape, + const GeomAPI_Shape::ShapeType& theType, + const GeomPointPtr& thePoint, + const double theTolerance) + { + std::list aSubs = theShape->subShapes(theType); + for (std::list::const_iterator aSubIt = aSubs.begin(); + aSubIt != aSubs.end(); ++aSubIt) { + if ((*aSubIt)->middlePoint()->distance(thePoint) < theTolerance) + return *aSubIt; + } + + // not found + return GeomShapePtr(); + } + + bool findSubshapeByPoint(const std::shared_ptr& theFeature, + const std::shared_ptr& thePoint, + const GeomAPI_Shape::ShapeType& theShapeType, + std::shared_ptr& theResult, + std::shared_ptr& theSubshape) + { + static const double TOLERANCE = 1.e-7; + + theResult = ResultPtr(); + const std::list& aResults = theFeature->results(); + for (std::list::const_iterator aResIt = aResults.begin(); + aResIt != aResults.end(); ++aResIt) { + GeomShapePtr aCurShape = (*aResIt)->shape(); + // first of all, check the point is within bounding box of the result + if (!aCurShape || !isPointWithinBB(thePoint, aCurShape, TOLERANCE)) + continue; + // now, process all sub-shapes of the given type and check their inner points, + // but skip the case the selected type is COMPOUND and the shape is a list of sketch edges + // (it will be processed later) + std::shared_ptr aSketchEdges = + std::dynamic_pointer_cast(aCurShape); + if (theShapeType != GeomAPI_Shape::COMPOUND || !aSketchEdges) + theSubshape = findSubShape(aCurShape, theShapeType, thePoint, TOLERANCE); + if (theSubshape) { + theResult = *aResIt; + break; + } + + // special case for ResultConstruction if the FACE is selected + ResultConstructionPtr aResConstr = + std::dynamic_pointer_cast(*aResIt); + if (aResConstr && theShapeType >= GeomAPI_Shape::FACE) { + int aNbFaces = aResConstr->facesNum(); + for (int aFaceInd = 0; aFaceInd < aNbFaces; ++aFaceInd) { + GeomFacePtr aCurFace = aResConstr->face(aFaceInd); + // check the point is within bounding box of the face + if (!isPointWithinBB(thePoint, aCurFace, TOLERANCE)) + continue; + theSubshape = findSubShape(aCurFace, theShapeType, thePoint, TOLERANCE); + if (theSubshape) { + theResult = *aResIt; + break; + } + } + } + if (theResult) + break; + + // next special case: the full sketch is selected + // the selection type is a COMPOUND + if (aSketchEdges && + aSketchEdges->middlePoint()->distance(thePoint) < TOLERANCE) { + // select whole result + theResult = *aResIt; + theSubshape = GeomShapePtr(); + break; + } + } + + return (bool)theResult; + } } // namespace ModelGeomAlgo_Shape