+ if (aWasWholeContext)
+ theShapes.Append(TopoDS_Shape());
+ else { // if theValShape exists in new context, add it without changes, otherwise - nothing
+ for (TopExp_Explorer aNew(aNewContShape, aValType); aNew.More(); aNew.Next()){
+ if (aNew.Current().IsSame(theValShape)) {
+ theShapes.Append(theValShape);
+ break;
+ }
+ }
+ }
+ } else if (theShapes.Size() > 1) {
+ // check it is possible to remove extra sub-shapes:
+ // keep only shapes with the same number of containers if possible
+ TopAbs_ShapeEnum anAncType = TopAbs_FACE;
+ if (aValType == TopAbs_VERTEX)
+ anAncType = TopAbs_EDGE;
+ TopoDS_Shape anOldContext = theOldContext->shape()->impl<TopoDS_Shape>();
+ TopTools_IndexedDataMapOfShapeListOfShape anOldMap;
+ TopExp::MapShapesAndUniqueAncestors(anOldContext, aValType, anAncType, anOldMap);
+ if (anOldMap.Contains(theValShape)) {
+ int aNumInOld = anOldMap.FindFromKey(theValShape).Extent();
+ TopTools_IndexedDataMapOfShapeListOfShape aNewMap;
+ TopExp::MapShapesAndUniqueAncestors(aNewContShape, aValType, anAncType, aNewMap);
+ TopTools_ListOfShape aNewResults;
+ for(TopTools_ListOfShape::Iterator aNewSubs(theShapes); aNewSubs.More(); aNewSubs.Next()) {
+ TopoDS_Shape aCand = aNewSubs.Value();
+ if (aNewMap.Contains(aCand) && aNewMap.FindFromKey(aCand).Extent() == aNumInOld)
+ aNewResults.Append(aCand);
+ }
+ if (!aNewResults.IsEmpty() && aNewResults.Size() < theShapes.Size())
+ theShapes = aNewResults;
+ }
+ }
+}
+
+
+void Model_AttributeSelection::concealedFeature(
+ const FeaturePtr theFeature, const FeaturePtr theStop, std::list<FeaturePtr>& theConcealers,
+ const ResultPtr theResultOfFeature)
+{
+ std::set<FeaturePtr> alreadyProcessed;
+ alreadyProcessed.insert(theFeature);
+ if (theStop.get())
+ alreadyProcessed.insert(theStop);
+ /// iterate all results to find the concealment-attribute
+ std::list<ResultPtr> aRootRes;
+ if (theResultOfFeature.get()) {
+ ResultPtr aRoot = ModelAPI_Tools::bodyOwner(theResultOfFeature, true);
+ aRootRes.push_back(aRoot ? aRoot : theResultOfFeature);
+ } else { // all results of a feature
+ aRootRes = theFeature->results();
+ }
+ std::list<ResultPtr>::const_iterator aRootIter = aRootRes.cbegin();
+ for(; aRootIter != aRootRes.cend(); aRootIter++) {
+ std::list<ResultPtr> allRes;
+ allRes.push_back(*aRootIter);
+ ResultBodyPtr aRootBody = ModelAPI_Tools::bodyOwner(*aRootIter, true);
+ if (!aRootBody.get())
+ aRootBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(*aRootIter);
+ if (aRootBody.get()) {
+ ModelAPI_Tools::allSubs(aRootBody, allRes);
+ }
+ for(std::list<ResultPtr>::iterator aRIter = allRes.begin(); aRIter != allRes.end(); aRIter++) {
+ const std::set<AttributePtr>& aRefs = (*aRIter)->data()->refsToMe();
+ std::set<AttributePtr>::const_iterator aRef = aRefs.cbegin();
+ for (; aRef != aRefs.cend(); aRef++) {
+ if (!aRef->get() || !(*aRef)->owner().get())
+ continue;
+ // concealed attribute only
+ FeaturePtr aRefFeat = std::dynamic_pointer_cast<ModelAPI_Feature>((*aRef)->owner());
+ if (alreadyProcessed.find(aRefFeat) != alreadyProcessed.end()) // optimization
+ continue;
+ alreadyProcessed.insert(aRefFeat);
+ if (ModelAPI_Session::get()->validators()->isConcealed(aRefFeat->getKind(), (*aRef)->id()))
+ {
+ // for extrusion cut in python script the nested sketch reference may be concealed before
+ // it is nested, so, check this composite feature is valid
+ static ModelAPI_ValidatorsFactory* aFactory = ModelAPI_Session::get()->validators();
+ // need to be validated to update the "Apply" state if not previewed
+ if (aFactory->validate(aRefFeat)) {
+ if (theStop.get()) {
+ std::shared_ptr<Model_Document> aDoc =
+ std::dynamic_pointer_cast<Model_Document>(theStop->document());
+ if (!aDoc->isLaterByDep(theStop, aRefFeat)) // skip feature later than stop
+ continue;
+ }
+ theConcealers.push_back(aRefFeat);
+ }
+ }
+ }
+ }