X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FModelAPI%2FModelAPI_Tools.cpp;h=c6b8a6f7257df6ba4933747cb038402399502a87;hb=ac53df4563f345f48d3a7274dbbb3f2618bacbda;hp=94699455931d940d5a77df7ee257cc12f4187b3f;hpb=abcf526d706b39afd25aab67b922cc903c626c9d;p=modules%2Fshaper.git diff --git a/src/ModelAPI/ModelAPI_Tools.cpp b/src/ModelAPI/ModelAPI_Tools.cpp old mode 100755 new mode 100644 index 946994559..c6b8a6f72 --- a/src/ModelAPI/ModelAPI_Tools.cpp +++ b/src/ModelAPI/ModelAPI_Tools.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 CEA/DEN, EDF R&D +// Copyright (C) 2014-2019 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -12,10 +12,9 @@ // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or -// email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // #include "ModelAPI_Tools.h" @@ -24,7 +23,8 @@ #include #include #include -#include +#include +#include #include #include #include @@ -107,6 +107,7 @@ std::shared_ptr shape(const ResultPtr& theResult) return theResult->shape(); } +// LCOV_EXCL_START const char* toString(ModelAPI_ExecState theExecState) { switch (theExecState) { @@ -159,6 +160,7 @@ std::string getFeatureError(const FeaturePtr& theFeature) return anError; } +// LCOV_EXCL_STOP ObjectPtr objectByName(const DocumentPtr& theDocument, const std::string& theGroup, const std::string& theName) @@ -265,66 +267,66 @@ CompositeFeaturePtr compositeOwner(const FeaturePtr& theFeature) return CompositeFeaturePtr(); // not found } -ResultCompSolidPtr compSolidOwner(const ResultPtr& theSub) +ResultBodyPtr bodyOwner(const ResultPtr& theSub, const bool theRoot) { - int anIndex; - ResultBodyPtr aBody = std::dynamic_pointer_cast(theSub); - if (aBody.get()) { - FeaturePtr aFeatureOwner = aBody->document()->feature(aBody); - if (aFeatureOwner.get()) { - std::list >::const_iterator aResIter = - aFeatureOwner->results().cbegin(); - for(; aResIter != aFeatureOwner->results().cend(); aResIter++) { - ResultCompSolidPtr aComp = std::dynamic_pointer_cast(*aResIter); - if (aComp && aComp->isSub(aBody, anIndex)) - return aComp; + if (theSub.get()) { + ObjectPtr aParent = theSub->document()->parent(theSub); + if (aParent.get()) { + if (theRoot) { // try to find parent of parent + ResultPtr aResultParent = std::dynamic_pointer_cast(aParent); + ResultBodyPtr aGrandParent = bodyOwner(aResultParent, true); + if (aGrandParent.get()) + aParent = aGrandParent; } + return std::dynamic_pointer_cast(aParent); } } - return ResultCompSolidPtr(); // not found + return ResultBodyPtr(); // not found } -int compSolidIndex(const ResultPtr& theSub) +int bodyIndex(const ResultPtr& theSub) { int anIndex = -1; - ResultBodyPtr aBody = std::dynamic_pointer_cast(theSub); - if (aBody.get()) { - FeaturePtr aFeatureOwner = aBody->document()->feature(aBody); - if (aFeatureOwner.get()) { - std::list >::const_iterator aResIter = - aFeatureOwner->results().cbegin(); - for(; aResIter != aFeatureOwner->results().cend(); aResIter++) { - ResultCompSolidPtr aComp = std::dynamic_pointer_cast(*aResIter); - if (aComp && aComp->isSub(aBody, anIndex)) - return anIndex; - } - } + ResultBodyPtr aParent = bodyOwner(theSub); + if (aParent.get()) { + ResultBodyPtr aBody = std::dynamic_pointer_cast(theSub); + if (aBody.get() && aParent->isSub(aBody, anIndex)) + return anIndex; } return anIndex; // not found } bool hasSubResults(const ResultPtr& theResult) { - ResultCompSolidPtr aCompSolid = std::dynamic_pointer_cast(theResult); + ResultBodyPtr aCompSolid = std::dynamic_pointer_cast(theResult); return aCompSolid.get() && aCompSolid->numberOfSubs() > 0; } +void allSubs(const ResultBodyPtr& theResult, std::list& theResults, + const bool theLowerOnly) { + // iterate sub-bodies of compsolid + ResultBodyPtr aComp = std::dynamic_pointer_cast(theResult); + if (aComp.get()) { + int aNumSub = aComp->numberOfSubs(); + for (int a = 0; a < aNumSub; a++) { + ResultBodyPtr aSub = aComp->subResult(a); + if (!theLowerOnly || aSub->numberOfSubs() == 0) + theResults.push_back(aSub); + allSubs(aSub, theResults); + } + } +} + void allResults(const FeaturePtr& theFeature, std::list& theResults) { if (!theFeature.get()) // safety: for empty feature no results return; const std::list >& aResults = theFeature->results(); - std::list >::const_iterator aRIter = aResults.begin(); + std::list::const_iterator aRIter = aResults.begin(); for (; aRIter != aResults.cend(); aRIter++) { theResults.push_back(*aRIter); - // iterate sub-bodies of compsolid - ResultCompSolidPtr aComp = std::dynamic_pointer_cast(*aRIter); - if (aComp.get()) { - int aNumSub = aComp->numberOfSubs(); - for(int a = 0; a < aNumSub; a++) { - theResults.push_back(aComp->subResult(a)); - } - } + ResultBodyPtr aResult = std::dynamic_pointer_cast(*aRIter); + allSubs(aResult, theResults); } } @@ -413,7 +415,6 @@ bool removeFeatures(const std::set& theFeatures, // \param theReferences an out container of references void addRefsToFeature(const FeaturePtr& theFeature, const std::map >& theReferencesMap, - std::map >& theProcessedReferences, int theRecLevel, std::set& theReferences) { @@ -421,34 +422,18 @@ void addRefsToFeature(const FeaturePtr& theFeature, return; theRecLevel++; - // if the feature is already processed, get the ready references from the map - if (theProcessedReferences.find(theFeature) != theProcessedReferences.end()) { - std::set aReferences = theProcessedReferences.at(theFeature); - theReferences.insert(aReferences.begin(), aReferences.end()); - return; - } - if (theReferencesMap.find(theFeature) == theReferencesMap.end()) return; // this feature is not in the selection list, so exists without references to it std::set aMainReferences = theReferencesMap.at(theFeature); std::set::const_iterator anIt = aMainReferences.begin(), aLast = aMainReferences.end(); -#ifdef DEBUG_REMOVE_FEATURES_RECURSE - std::string aSpacing; - for (int i = 0; i < theRecLevel; i++) - aSpacing.append(" "); -#endif - for (; anIt != aLast; anIt++) { FeaturePtr aRefFeature = *anIt; -#ifdef DEBUG_REMOVE_FEATURES_RECURSE - std::cout << aSpacing << " Ref: " << getFeatureInfo(aRefFeature) << std::endl; -#endif - if (theReferences.find(aRefFeature) == theReferences.end()) + if (theReferences.find(aRefFeature) == theReferences.end()) { + addRefsToFeature(aRefFeature, theReferencesMap, theRecLevel, theReferences); theReferences.insert(aRefFeature); - addRefsToFeature(aRefFeature, theReferencesMap, theProcessedReferences, - theRecLevel, theReferences); + } } } @@ -556,7 +541,7 @@ void findAllReferences(const std::set& theFeatures, std::cout << " Ref: " << getFeatureInfo(aFeature) << std::endl; #endif aRecLevel++; - addRefsToFeature(aFeature, aMainList, theReferences, + addRefsToFeature(aFeature, aMainList, aRecLevel, aResultRefList/*aMainRefList*/); } theReferences[aMainListFeature] = aResultRefList; @@ -623,58 +608,61 @@ void getConcealedResults(const FeaturePtr& theFeature, } } -std::pair getDefaultName( - const std::shared_ptr& theResult, - const int theResultIndex) +std::pair getDefaultName(const std::shared_ptr& theResult, + const bool theInherited) { typedef std::list< std::pair < std::string, std::list > > ListOfReferences; SessionPtr aSession = ModelAPI_Session::get(); - FeaturePtr anOwner = ModelAPI_Feature::feature(theResult->data()->owner()); - ResultCompSolidPtr aCompSolidRes = compSolidOwner(theResult); - if (aCompSolidRes) { + 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 << anOwner->name(); - // compute default name of CompSolid (name of feature + index of CompSolid's result) - int aCompSolidResultIndex = 0; - const std::list& aResults = anOwner->results(); - for (std::list::const_iterator anIt = aResults.begin(); - anIt != aResults.end(); ++anIt, ++aCompSolidResultIndex) - if (aCompSolidRes == *anIt) - break; - aDefaultName << "_" << (aCompSolidResultIndex + 1) << "_" << (theResultIndex + 1); + aDefaultName << getDefaultName(anOwnerRes).first; + aDefaultName << "_" << (bodyIndex(theResult) + 1); return std::pair(aDefaultName.str(), false); } + FeaturePtr anOwner = ModelAPI_Feature::feature(theResult->data()->owner()); DataPtr aData = anOwner->data(); ListOfReferences aReferences; - aData->referencesToObjects(aReferences); - // find first result with user-defined name ListOfReferences::const_iterator aFoundRef = aReferences.end(); - for (ListOfReferences::const_iterator aRefIt = aReferences.begin(); - aRefIt != aReferences.end(); ++aRefIt) { - bool isConcealed = aSession->validators()->isConcealed(anOwner->getKind(), aRefIt->first); - bool isMainArg = isConcealed && - aSession->validators()->isMainArgument(anOwner->getKind(), aRefIt->first); - if (isConcealed) { - // check the referred object is a Body - // (for example, ExtrusionCut has a sketch as a first attribute which is concealing) - bool isBody = aRefIt->second.size() > 1 || (aRefIt->second.size() == 1 && - aRefIt->second.front()->groupName() == ModelAPI_ResultBody::group()); - if (isBody && (isMainArg || aFoundRef == aReferences.end() || - aData->isPrecedingAttribute(aRefIt->first, aFoundRef->first))) - aFoundRef = aRefIt; - - if (isMainArg) - break; + if (theInherited) { + aData->referencesToObjects(aReferences); + + for (ListOfReferences::const_iterator aRefIt = aReferences.begin(); + aRefIt != aReferences.end(); ++aRefIt) { + bool isConcealed = aSession->validators()->isConcealed(anOwner->getKind(), aRefIt->first); + bool isMainArg = isConcealed && + aSession->validators()->isMainArgument(anOwner->getKind(), aRefIt->first); + if (isConcealed) { + // check the referred object is a Body + // (for example, ExtrusionCut has a sketch as a first attribute which is concealing) + bool isBody = aRefIt->second.size() > 1 || (aRefIt->second.size() == 1 && + aRefIt->second.front()->groupName() == ModelAPI_ResultBody::group()); + if (isBody && (isMainArg || aFoundRef == aReferences.end() || + aData->isPrecedingAttribute(aRefIt->first, aFoundRef->first))) + aFoundRef = aRefIt; + + if (isMainArg) + break; + } } } + // get the result number in the feature + int anIndexInOwner = 0; + const std::list& anOwnerResults = anOwner->results(); + std::list::const_iterator aResIt = anOwnerResults.cbegin(); + for(; aResIt != anOwnerResults.cend(); aResIt++) { + if(*aResIt == theResult) + break; + anIndexInOwner++; + } // find an object which is concealed by theResult if (aFoundRef != aReferences.end() && !aFoundRef->second.empty()) { @@ -682,12 +670,12 @@ std::pair getDefaultName( std::map aNbRefToObject; // search the object by result index std::list::const_iterator anObjIt = aFoundRef->second.begin(); - int aResultIndex = theResultIndex; + int aResultIndex = anIndexInOwner; while (--aResultIndex >= 0) { ResultPtr aCurRes = std::dynamic_pointer_cast(*anObjIt); - ResultCompSolidPtr aParentCompSolid = ModelAPI_Tools::compSolidOwner(aCurRes); - if (aParentCompSolid) - aCurRes = aParentCompSolid; + ResultBodyPtr aParentBody = ModelAPI_Tools::bodyOwner(aCurRes); + if (aParentBody) + aCurRes = aParentBody; if (aNbRefToObject.find(aCurRes) == aNbRefToObject.end()) aNbRefToObject[aCurRes] = 1; else @@ -703,9 +691,9 @@ std::pair getDefaultName( if ((*anObjIt)->groupName() == ModelAPI_ResultBody::group()) { // check the result is part of CompSolid ResultPtr anObjRes = std::dynamic_pointer_cast(*anObjIt); - ResultCompSolidPtr aParentCompSolid = ModelAPI_Tools::compSolidOwner(anObjRes); - if (aParentCompSolid) - anObjRes = aParentCompSolid; + ResultBodyPtr aParentBody = ModelAPI_Tools::bodyOwner(anObjRes); + if (aParentBody) + anObjRes = aParentBody; // return name of reference result only if it has been renamed by the user, // in other case compose a default name @@ -728,9 +716,72 @@ std::pair getDefaultName( aDefaultName << anOwner->name(); // if there are several results (issue #899: any number of result), // add unique prefix starting from second - if (theResultIndex > 0 || theResult->groupName() == ModelAPI_ResultBody::group()) - aDefaultName << "_" << theResultIndex + 1; + if (anIndexInOwner > 0 || theResult->groupName() == ModelAPI_ResultBody::group()) + aDefaultName << "_" << anIndexInOwner + 1; return std::pair(aDefaultName.str(), false); } +std::set getParents(const FeaturePtr& theFeature) +{ + std::set aParents; + for (FeaturePtr aCurFeat = theFeature; aCurFeat; ) { + CompositeFeaturePtr aFoundComposite; + const std::set& aRefs = aCurFeat->data()->refsToMe(); + for (std::set::const_iterator anIt = aRefs.begin(); + anIt != aRefs.end(); ++anIt) { + FeaturePtr aF = ModelAPI_Feature::feature((*anIt)->owner()); + aFoundComposite = std::dynamic_pointer_cast(aF); + if (aFoundComposite && aFoundComposite->isSub(aCurFeat)) + break; + else + aFoundComposite = CompositeFeaturePtr(); + } + + if (aFoundComposite) { + aParents.insert(aFoundComposite); + aCurFeat = aFoundComposite; + } + else { + // add the part containing high-level feature + SessionPtr aSession = ModelAPI_Session::get(); + DocumentPtr aPartSetDoc = aSession->moduleDocument(); + std::list aPartSetFeatures = aPartSetDoc->allFeatures(); + for (std::list::const_iterator anIt = aPartSetFeatures.begin(); + anIt != aPartSetFeatures.end(); ++anIt) { + aFoundComposite = std::dynamic_pointer_cast(*anIt); + if (aFoundComposite && aFoundComposite->isSub(aCurFeat)) { + aParents.insert(aFoundComposite); + break; + } + } + + aCurFeat = FeaturePtr(); + } + } + return aParents; +} + +void removeResults(const std::list& theResults) +{ + // collect all documents where the results must be removed + std::map > aDocs; + + std::list::const_iterator aResIter = theResults.cbegin(); + for(; aResIter != theResults.cend(); aResIter++) { + DocumentPtr aDoc = (*aResIter)->document(); + if (!aDocs.count(aDoc)) + aDocs[aDoc] = std::list(); + aDocs[aDoc].push_back(*aResIter); + } + // create a "remove" feature in each doc + std::map >::iterator aDoc = aDocs.begin(); + for(; aDoc != aDocs.end(); aDoc++) { + FeaturePtr aRemove = aDoc->first->addFeature("RemoveResults"); + if (aRemove) { + for(aResIter = aDoc->second.cbegin(); aResIter != aDoc->second.cend(); aResIter++) + aRemove->selectionList("results")->append(*aResIter, GeomShapePtr()); + } + } +} + } // namespace ModelAPI_Tools