#include <ModelAPI_Feature.h>
#include <ModelAPI_Result.h>
+#include <ModelAPI_ResultConstruction.h>
+
+#include <GeomAPI_PlanarEdges.h>
+#include <GeomAPI_Pnt.h>
#ifdef WIN32
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<GeomShapePtr> aSubs = theShape->subShapes(theType);
+ for (std::list<GeomShapePtr>::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<ModelAPI_Feature>& theFeature,
+ const std::shared_ptr<GeomAPI_Pnt>& thePoint,
+ const GeomAPI_Shape::ShapeType& theShapeType,
+ std::shared_ptr<ModelAPI_Result>& theResult,
+ std::shared_ptr<GeomAPI_Shape>& theSubshape)
+ {
+ static const double TOLERANCE = 1.e-7;
+
+ theResult = ResultPtr();
+ const std::list<ResultPtr>& aResults = theFeature->results();
+ for (std::list<ResultPtr>::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<GeomAPI_PlanarEdges> aSketchEdges =
+ std::dynamic_pointer_cast<GeomAPI_PlanarEdges>(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<ModelAPI_ResultConstruction>(*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