+static int possibleSelectionsByPoint(const GeomPointPtr& thePoint,
+ const ResultPtr& theResult,
+ const GeomShapePtr& theShape,
+ const FeaturePtr& theStartFeature,
+ const FeaturePtr& theEndFeature)
+{
+ DocumentPtr aDoc1 = theStartFeature->document();
+ DocumentPtr aDoc2 = theEndFeature->document();
+
+ std::list<FeaturePtr> aFeatures = aDoc1->allFeatures();
+ if (aDoc1 != aDoc2) {
+ std::list<FeaturePtr> anAdditionalFeatures = aDoc2->allFeatures();
+ aFeatures.insert(aFeatures.end(), anAdditionalFeatures.begin(), anAdditionalFeatures.end());
+ }
+
+ CompositeFeaturePtr aLastCompositeFeature;
+
+ std::list<FeaturePtr>::const_iterator aFIt = aFeatures.begin();
+ while (aFIt != aFeatures.end() && *aFIt != theStartFeature) {
+ CompositeFeaturePtr aCompFeat = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(*aFIt);
+ if (aCompFeat)
+ aLastCompositeFeature = aCompFeat;
+ ++aFIt;
+ }
+
+ // collect the list of composite features, containing the last feature;
+ // these features should be excluded from searching,
+ // because the feature cannot select sub-shapes from its parent
+ std::set<FeaturePtr> aEndFeatureParents = ModelAPI_Tools::getParents(theEndFeature);
+
+ int aNbPossibleSelections = 0;
+ for (; aFIt != aFeatures.end() && *aFIt != theEndFeature; ++aFIt) {
+ bool isSkipFeature = false;
+ if (aLastCompositeFeature && aLastCompositeFeature->isSub(*aFIt))
+ isSkipFeature = true;
+ CompositeFeaturePtr aCompFeat = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(*aFIt);
+ if (aCompFeat) {
+ ResultPartPtr aPartRes =
+ std::dynamic_pointer_cast<ModelAPI_ResultPart>(aCompFeat->firstResult());
+ if (!aPartRes)
+ aLastCompositeFeature = aCompFeat;
+ if (aEndFeatureParents.find(aCompFeat) != aEndFeatureParents.end()) {
+ // do not process the parent for the last feature,
+ // because it cannot select objects from its parent
+ isSkipFeature = true;
+ }
+ }
+ if (isSkipFeature)
+ continue;
+
+ std::list<ModelGeomAlgo_Shape::SubshapeOfResult> anApproproate;
+ if (ModelGeomAlgo_Shape::findSubshapeByPoint(*aFIt, thePoint, theShape->shapeType(),
+ anApproproate)) {
+ std::list<ModelGeomAlgo_Shape::SubshapeOfResult>::iterator anApIt = anApproproate.begin();
+ for (; anApIt != anApproproate.end(); ++anApIt) {
+ ++aNbPossibleSelections;
+
+ // stop if the target shape and result are found
+ GeomShapePtr aCurShape = anApIt->mySubshape;
+ if (!aCurShape)
+ aCurShape = anApIt->myResult->shape();
+
+ if (anApIt->myResult->isSame(theResult) && aCurShape->isSame(theShape))
+ break;
+ }
+ }
+ }
+ return aNbPossibleSelections;
+}
+