+ // another try to find edge or vertex by faces
+ std::list<std::string> aListofNames;
+ size_t aN = aSelection.IsNull() ? ParseName(theSubShapeName, aListofNames) : 0;
+ if (aSelection.IsNull() && (aType == TopAbs_EDGE || aType == TopAbs_VERTEX)) {
+ if(aN > 1 && (aN < 4 || (aType == TopAbs_EDGE && aN < 5))) { // 2 || 3 or 4 for EDGE
+ TopTools_ListOfShape aList;
+ std::list<std::string>::iterator it = aListofNames.begin();
+ for(; it != aListofNames.end(); it++){
+ const TopoDS_Shape aFace = findFaceByName(*it, theDoc);
+ if(!aFace.IsNull())
+ aList.Append(aFace);
+ }
+ aSelection = findCommonShape(aType, aList);
+ }
+ }
+ if (!aSelection.IsNull()) {// Select it
+ std::shared_ptr<GeomAPI_Shape> aShapeToBeSelected(new GeomAPI_Shape());
+ aShapeToBeSelected->setImpl(new TopoDS_Shape(aSelection));
+ theShapeToBeSelected = aShapeToBeSelected;
+ theCont = aCont;
+ return true;
+ }
+ // in case of construction, there is no registered names for all sub-elements,
+ // even for the main element; so, trying to find them by name (without "&" intersections)
+ if (aN == 0) {
+ size_t aConstrNamePos = theSubShapeName.find("/");
+ bool isFullName = aConstrNamePos == std::string::npos;
+ std::string aContrName =
+ isFullName ? theSubShapeName : theSubShapeName.substr(0, aConstrNamePos);
+ ResultPtr aConstr = theDoc->findByName(aContrName);
+ if (aConstr.get() && aConstr->groupName() == ModelAPI_ResultConstruction::group()) {
+ theCont = aConstr;
+ if (isFullName) {
+ theShapeToBeSelected = aConstr->shape();
+ return true;
+ }
+ // for sketch sub-elements selected
+ CompositeFeaturePtr aComposite =
+ std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(theDoc->feature(aConstr));
+ if (aComposite.get()) {
+ if (aType == TopAbs_VERTEX || aType == TopAbs_EDGE) {
+ // collect all IDs in the name
+ std::map<int, bool> anIDs;
+ if (!parseSubIndices(theSubShapeName, aType == TopAbs_EDGE ? "Edge" : "Vertex", anIDs))
+ return false;
+
+ const int aSubNum = aComposite->numberOfSubs();
+ for(int a = 0; a < aSubNum; a++) {
+ int aCompID = aComposite->subFeatureId(a);
+ if (anIDs.find(aCompID) != anIDs.end()) { // found the vertex/edge shape
+ FeaturePtr aSub = aComposite->subFeature(a);
+ ResultConstructionPtr aV = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>
+ (*(aSub->results().begin()));
+ if (aV) {
+ theShapeToBeSelected = aV->shape();
+ return true;
+ }
+ } else if (aType == TopAbs_VERTEX &&
+ (anIDs.find(aCompID + kSTART_VERTEX_DELTA) != anIDs.end() ||
+ anIDs.find(aCompID + 2 * kSTART_VERTEX_DELTA) != anIDs.end())) {
+ FeaturePtr aSub = aComposite->subFeature(a);
+ const std::list<std::shared_ptr<ModelAPI_Result> >& aResults = aSub->results();
+ std::list<std::shared_ptr<ModelAPI_Result> >::const_iterator aRes = aResults.cbegin();
+ // there may be many shapes (circle and center)
+ for(; aRes != aResults.cend(); aRes++) {
+ ResultConstructionPtr aE =
+ std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*aRes);
+ if (aE && aE->shape()->isEdge()) {
+ const TopoDS_Shape& anEdge = aE->shape()->impl<TopoDS_Shape>();
+ TopExp_Explorer aVExp(anEdge, TopAbs_VERTEX); // first vertex
+ if (anIDs.find(aCompID + kSTART_VERTEX_DELTA) == anIDs.end())
+ aVExp.Next(); // second vertex
+ std::shared_ptr<GeomAPI_Shape> aShapeToBeSelected(new GeomAPI_Shape());
+ aShapeToBeSelected->setImpl(new TopoDS_Shape(aVExp.Current()));
+ theShapeToBeSelected = aShapeToBeSelected;
+ return true;
+ }
+ }
+ }
+ }
+ } else if (aType == TopAbs_FACE) { // sketch faces is identified by format "Sketch_1/Face-2f-8f-11r"
+ std::map<int, bool> anIDs;
+ if (!parseSubIndices(theSubShapeName, "Face", anIDs, true))
+ return false;
+
+ NCollection_DataMap<Handle(Geom_Curve), int> allCurves; // curves and orientations of edges
+ const int aSubNum = aComposite->numberOfSubs();
+ for(int a = 0; a < aSubNum; a++) {
+ int aSubID = aComposite->subFeatureId(a);
+ if (anIDs.find(aSubID) != anIDs.end()) {
+ FeaturePtr aSub = aComposite->subFeature(a);
+ const std::list<std::shared_ptr<ModelAPI_Result> >& aResults = aSub->results();
+ std::list<std::shared_ptr<ModelAPI_Result> >::const_iterator aRes;
+ for(aRes = aResults.cbegin(); aRes != aResults.cend(); aRes++) {
+ ResultConstructionPtr aConstr =
+ std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*aRes);
+ if (aConstr->shape() && aConstr->shape()->isEdge()) {
+ const TopoDS_Shape& aResShape = aConstr->shape()->impl<TopoDS_Shape>();
+ TopoDS_Edge anEdge = TopoDS::Edge(aResShape);
+ if (!anEdge.IsNull()) {
+ Standard_Real aFirst, aLast;
+ Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast);
+ allCurves.Bind(aCurve, anIDs[aSubID] ? 1 : -1);
+ }
+ }
+ }
+ }
+ }
+ std::shared_ptr<GeomAPI_Shape> aFoundFace = findAppropriateFace(aConstr, allCurves);
+ if (aFoundFace.get()) {
+ theShapeToBeSelected = aFoundFace;
+ return true;
+ }
+ }
+ }
+ }
+ }