+ theRecLevel++;
+ std::set<FeaturePtr>::const_iterator anIt = theFeatures.begin(),
+ aLast = theFeatures.end();
+ for (; anIt != aLast; anIt++) {
+ FeaturePtr aFeature = *anIt;
+ if (aFeature.get() && theReferences.find(aFeature) == theReferences.end()) {
+ DocumentPtr aSelFeatureDoc = aFeature->document();
+ std::set<FeaturePtr> aSelRefFeatures;
+ aSelFeatureDoc->refsToFeature(aFeature, aSelRefFeatures, false/*do not emit signals*/);
+ if (theUseComposite) { // do not filter selection
+ theReferences[aFeature] = aSelRefFeatures;
+ }
+ else { // filter references to skip composition features of the current feature
+ std::set<FeaturePtr> aFilteredFeatures;
+ std::set<FeaturePtr>::const_iterator anIt = aSelRefFeatures.begin(),
+ aLast = aSelRefFeatures.end();
+ for (; anIt != aLast; anIt++) {
+ FeaturePtr aCFeature = *anIt;
+ CompositeFeaturePtr aComposite =
+ std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aCFeature);
+ if (aComposite.get() && aComposite->isSub(aFeature))
+ continue; /// composite of the current feature should be skipped
+ aFilteredFeatures.insert(aCFeature);
+ }
+ theReferences[aFeature] = aFilteredFeatures;
+ }
+ if (theUseRecursion) {
+#ifdef DEBUG_CYCLING_1550
+ findReferences(aSelRefFeatures, theReferences, theUseComposite,
+ theUseRecursion, theRecLevel);
+#else
+ findReferences(theReferences[aFeature], theReferences, theUseComposite, theUseRecursion,
+ theRecLevel);
+#endif
+ }
+ }
+ }
+}
+
+void findAllReferences(const std::set<FeaturePtr>& theFeatures,
+ std::map<FeaturePtr, std::set<FeaturePtr> >& theReferences,
+ const bool theUseComposite,
+ const bool theUseRecursion)
+{
+ // For dependencies, find main_list:
+ // sk_1(ext_1, vertex_1)
+ // ext_1(bool_1, sk_3)
+ // vertex_1()
+ // sk_2(ext_2)
+ // ext_2(bool_2)
+ // sk_3()
+ // Information: bool_1 is not selected, ext_2(bool_2) exists
+ // find all referenced features
+ std::map<FeaturePtr, std::set<FeaturePtr> > aMainList;
+ int aRecLevel = 0;
+ findReferences(theFeatures, aMainList, theUseComposite, theUseRecursion, aRecLevel);
+
+#ifdef DEBUG_REMOVE_FEATURES
+ printMapInfo(aMainList, "firstDependencies");
+#endif
+ // find all dependencies for each object:
+ // sk_1(ext_1, vertex_1) + (sk_3, bool_1)
+ // ext_1(bool_1, sk_3)
+ // vertex_1()
+ // sk_2(ext_2) + (bool_1)
+ // ext_2(bool_1)
+ // sk_3()
+ std::map<FeaturePtr, std::set<FeaturePtr> >::const_iterator aMainIt = aMainList.begin(),
+ aMainLast = aMainList.end();
+ for (; aMainIt != aMainLast; aMainIt++) {
+ FeaturePtr aMainListFeature = aMainIt->first;
+
+ //std::string aName = aMainListFeature->name();
+ std::set<FeaturePtr> aMainRefList = aMainIt->second;
+
+#ifdef DEBUG_REMOVE_FEATURES_RECURSE
+ char aBuf[50];
+ int n = sprintf(aBuf, "%d", aMainRefList.size());
+ std::string aSize(aBuf);
+ std::cout << "_findAllReferences for the Feature: " << getFeatureInfo(aMainListFeature)
+ << ", references size = " << aSize << std::endl;
+#endif
+ std::set<FeaturePtr>::const_iterator anIt = aMainRefList.begin(),
+ aLast = aMainRefList.end();
+ std::set<FeaturePtr> aResultRefList;
+ aResultRefList.insert(aMainRefList.begin(), aMainRefList.end());
+ for (; anIt != aLast; anIt++) {
+ FeaturePtr aFeature = *anIt;
+ int aRecLevel = 0;
+#ifdef DEBUG_REMOVE_FEATURES_RECURSE
+ std::cout << " Ref: " << getFeatureInfo(aFeature) << std::endl;
+#endif
+ aRecLevel++;
+ addRefsToFeature(aFeature, aMainList,
+ aRecLevel, aResultRefList/*aMainRefList*/);
+ }
+ theReferences[aMainListFeature] = aResultRefList;
+ }
+#ifdef DEBUG_REMOVE_FEATURES_RECURSE
+ std::cout << std::endl;
+#endif
+
+#ifdef DEBUG_REMOVE_FEATURES
+ printMapInfo(theReferences, "allDependencies");
+#endif
+}
+
+void findRefsToFeatures(const std::set<FeaturePtr>& theFeatures,
+ const std::map<FeaturePtr, std::set<FeaturePtr> >& theReferences,
+ std::set<FeaturePtr>& theFeaturesRefsTo)
+{
+ std::set<FeaturePtr>::const_iterator anIt = theFeatures.begin(),
+ aLast = theFeatures.end();
+ for (; anIt != aLast; anIt++) {
+ FeaturePtr aFeature = *anIt;
+ if (theReferences.find(aFeature) == theReferences.end())
+ continue;
+ std::set<FeaturePtr> aRefList = theReferences.at(aFeature);
+ std::set<FeaturePtr>::const_iterator aRefIt = aRefList.begin(), aRefLast = aRefList.end();
+ for (; aRefIt != aRefLast; aRefIt++) {
+ FeaturePtr aRefFeature = *aRefIt;
+ CompositeFeaturePtr aComposite =
+ std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aRefFeature);
+ if (aComposite.get() && aComposite->isSub(aFeature))
+ continue; /// composite of the current feature should not be removed
+
+ if (theFeatures.find(aRefFeature) == theFeatures.end() && // it is not selected
+ theFeaturesRefsTo.find(aRefFeature) == theFeaturesRefsTo.end()) // it is not added
+ theFeaturesRefsTo.insert(aRefFeature);
+ }
+ }
+}
+
+void getConcealedResults(const FeaturePtr& theFeature,
+ std::list<std::shared_ptr<ModelAPI_Result> >& theResults)
+{
+ SessionPtr aSession = ModelAPI_Session::get();
+
+ std::list<std::pair<std::string, std::list<std::shared_ptr<ModelAPI_Object> > > > aRefs;
+ theFeature->data()->referencesToObjects(aRefs);
+ std::list<std::pair<std::string, std::list<ObjectPtr> > >::const_iterator
+ anIt = aRefs.begin(), aLast = aRefs.end();
+ std::set<ResultPtr> alreadyThere; // to avoid duplications
+ for (; anIt != aLast; anIt++) {
+ if (!aSession->validators()->isConcealed(theFeature->getKind(), anIt->first))
+ continue; // use only concealed attributes
+ std::list<ObjectPtr> anObjects = (*anIt).second;
+ std::list<ObjectPtr>::const_iterator anOIt = anObjects.begin(), anOLast = anObjects.end();
+ for (; anOIt != anOLast; anOIt++) {
+ ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(*anOIt);
+ if (aResult && aResult->isConcealed()) {
+ if (alreadyThere.find(aResult) == alreadyThere.end()) // issue 1712, avoid duplicates
+ alreadyThere.insert(aResult);
+ else continue;
+ theResults.push_back(aResult);
+ }
+ }
+ }
+}
+
+std::pair<std::string, bool> getDefaultName(const std::shared_ptr<ModelAPI_Result>& theResult,
+ const bool theInherited)
+{
+ typedef std::list< std::pair < std::string, std::list<ObjectPtr> > > ListOfReferences;
+
+ SessionPtr aSession = ModelAPI_Session::get();
+
+ ResultBodyPtr anOwnerRes = bodyOwner(theResult);
+ if (anOwnerRes) {
+ // names of sub-solids in CompSolid should be default (for example,
+ // result of boolean operation 'Boolean_1_1' is a CompSolid which is renamed to 'MyBOOL',
+ // however, sub-elements of 'MyBOOL' should be named 'Boolean_1_1_1', 'Boolean_1_1_2' etc.)
+ std::ostringstream aDefaultName;
+ aDefaultName << getDefaultName(anOwnerRes).first;
+ aDefaultName << "_" << (bodyIndex(theResult) + 1);
+ return std::pair<std::string, bool>(aDefaultName.str(), false);
+ }
+
+ FeaturePtr anOwner = ModelAPI_Feature::feature(theResult->data()->owner());
+ DataPtr aData = anOwner->data();