X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FModelAPI%2FModelAPI_Tools.cpp;h=ddd809ed663406e81dc2b5ac33420137c41a8ed9;hb=d7a6c25deae913bdee575372b0ccea7e041c9b5c;hp=ee9de24e129e5140d0e996d7ae456f0b0c48692c;hpb=8193b76f73047e852eaecfb4c0ff86cf44e1f8c9;p=modules%2Fshaper.git diff --git a/src/ModelAPI/ModelAPI_Tools.cpp b/src/ModelAPI/ModelAPI_Tools.cpp index ee9de24e1..ddd809ed6 100755 --- a/src/ModelAPI/ModelAPI_Tools.cpp +++ b/src/ModelAPI/ModelAPI_Tools.cpp @@ -1,14 +1,30 @@ -// Copyright (C) 2014-20xx CEA/DEN, EDF R&D - -// File: ModelAPI_Tools.cpp -// Created: 06 Aug 2014 -// Author: Vitaly Smetannikov +// Copyright (C) 2014-2017 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 +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// 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 +// +// See http://www.salome-platform.org/ or +// email : webmaster.salome@opencascade.com +// #include "ModelAPI_Tools.h" #include +#include #include #include #include +#include #include #include #include @@ -16,6 +32,7 @@ #include #include #include +#include #include #include @@ -90,21 +107,7 @@ std::shared_ptr shape(const ResultPtr& theResult) return theResult->shape(); } -void shapesOfType(const FeaturePtr& theFeature, - const GeomAPI_Shape::ShapeType& theType, - std::set& theShapes) -{ - std::list aResults = theFeature->results(); - std::list::const_iterator aRIter = aResults.cbegin(); - for (; aRIter != aResults.cend(); aRIter++) { - ResultPtr aResult = *aRIter; - GeomShapePtr aShape = aResult->shape(); - if (aShape.get() && aShape->shapeType() == theType) - theShapes.insert(aShape); - } -} - -const char* toString(ModelAPI_ExecState theExecState) +const char* toString(ModelAPI_ExecState theExecState) { #define TO_STRING(__NAME__) case __NAME__: return #__NAME__; switch (theExecState) { @@ -159,7 +162,8 @@ std::string getFeatureError(const FeaturePtr& theFeature) return anError; } -ObjectPtr objectByName(const DocumentPtr& theDocument, const std::string& theGroup, const std::string& theName) +ObjectPtr objectByName(const DocumentPtr& theDocument, const std::string& theGroup, + const std::string& theName) { for (int anIndex = 0; anIndex < theDocument->size(theGroup); ++anIndex) { ObjectPtr anObject = theDocument->object(theGroup, anIndex); @@ -178,15 +182,19 @@ bool findVariable(const DocumentPtr& theDocument, FeaturePtr theSearcher, if (!theParam.get()) return false; // avoid usage of parameters created later than the initial parameter - if (theSearcher.get() && theDocument->isLater(theDocument->feature(theParam), theSearcher)) - return false; + + if (theSearcher.get()) { + FeaturePtr aParamFeat = theDocument->feature(theParam); + if (aParamFeat == theSearcher || theDocument->isLater(aParamFeat, theSearcher)) + return false; + } AttributeDoublePtr aValueAttribute = theParam->data()->real(ModelAPI_ResultParameter::VALUE()); outValue = aValueAttribute->value(); return true; } -bool findVariable(FeaturePtr theSearcher, const std::string& theName, double& outValue, ResultParameterPtr& theParam, - const DocumentPtr& theDocument) +bool findVariable(FeaturePtr theSearcher, const std::string& theName, double& outValue, + ResultParameterPtr& theParam, const DocumentPtr& theDocument) { SessionPtr aSession = ModelAPI_Session::get(); std::list aDocList; @@ -204,7 +212,9 @@ bool findVariable(FeaturePtr theSearcher, const std::string& theName, double& ou ResultPtr findPartResult(const DocumentPtr& theMain, const DocumentPtr& theSub) { - if (theMain != theSub) { // to optimize and avoid of crash on partset document close (don't touch the sub-document structure) + // to optimize and avoid of crash on partset document close + // (don't touch the sub-document structure) + if (theMain != theSub) { for (int a = theMain->size(ModelAPI_ResultPart::group()) - 1; a >= 0; a--) { ResultPartPtr aPart = std::dynamic_pointer_cast( theMain->object(ModelAPI_ResultPart::group(), a)); @@ -218,8 +228,12 @@ ResultPtr findPartResult(const DocumentPtr& theMain, const DocumentPtr& theSub) FeaturePtr findPartFeature(const DocumentPtr& theMain, const DocumentPtr& theSub) { - if (theMain != theSub) { // to optimize and avoid of crash on partset document close (don't touch the sub-document structure) - for (int a = theMain->size(ModelAPI_Feature::group()) - 1; a >= 0; a--) { + // to optimize and avoid of crash on partset document close + // (don't touch the sub-document structure) + if (theMain != theSub) { + // iteration from top to bottom to avoid finding the movement documents before the original + int aSize = theMain->size(ModelAPI_Feature::group()); + for (int a = 0; a < aSize; a++) { FeaturePtr aPartFeat = std::dynamic_pointer_cast( theMain->object(ModelAPI_Feature::group(), a)); if (aPartFeat.get()) { @@ -240,7 +254,7 @@ FeaturePtr findPartFeature(const DocumentPtr& theMain, const DocumentPtr& theSub CompositeFeaturePtr compositeOwner(const FeaturePtr& theFeature) { - if (theFeature.get() && theFeature->data()->isValid()) { + if (theFeature.get() && theFeature->data() && theFeature->data()->isValid()) { const std::set >& aRefs = theFeature->data()->refsToMe(); std::set >::const_iterator aRefIter = aRefs.begin(); for(; aRefIter != aRefs.end(); aRefIter++) { @@ -255,15 +269,16 @@ CompositeFeaturePtr compositeOwner(const FeaturePtr& theFeature) ResultCompSolidPtr compSolidOwner(const ResultPtr& theSub) { + 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 = + 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)) + if (aComp && aComp->isSub(aBody, anIndex)) return aComp; } } @@ -271,6 +286,25 @@ ResultCompSolidPtr compSolidOwner(const ResultPtr& theSub) return ResultCompSolidPtr(); // not found } +int compSolidIndex(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; + } + } + } + return anIndex; // not found +} + bool hasSubResults(const ResultPtr& theResult) { ResultCompSolidPtr aCompSolid = std::dynamic_pointer_cast(theResult); @@ -348,6 +382,7 @@ bool removeFeaturesAndReferences(const std::set& theFeatures, return ModelAPI_Tools::removeFeatures(aFeatures, false); } +//*********************************************************************** bool removeFeatures(const std::set& theFeatures, const bool theFlushRedisplay) { @@ -364,13 +399,15 @@ bool removeFeatures(const std::set& theFeatures, } } if (isDone && theFlushRedisplay) { - // the redisplay signal should be flushed in order to erase the feature presentation in the viewer + // the redisplay signal should be flushed in order to erase + // the feature presentation in the viewer // if should be done after removeFeature() of document Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY)); } return true; } +//*********************************************************************** // Fills the references list by all references of the feature from the references map. // This is a recusive method to find references by next found feature in the map of references. // \param theFeature a feature to find references @@ -412,7 +449,8 @@ void addRefsToFeature(const FeaturePtr& theFeature, #endif if (theReferences.find(aRefFeature) == theReferences.end()) theReferences.insert(aRefFeature); - addRefsToFeature(aRefFeature, theReferencesMap, theProcessedReferences, theRecLevel, theReferences); + addRefsToFeature(aRefFeature, theReferencesMap, theProcessedReferences, + theRecLevel, theReferences); } } @@ -445,7 +483,8 @@ void findReferences(const std::set& theFeatures, aLast = aSelRefFeatures.end(); for (; anIt != aLast; anIt++) { FeaturePtr aCFeature = *anIt; - CompositeFeaturePtr aComposite = std::dynamic_pointer_cast(aCFeature); + CompositeFeaturePtr aComposite = + std::dynamic_pointer_cast(aCFeature); if (aComposite.get() && aComposite->isSub(aFeature)) continue; /// composite of the current feature should be skipped aFilteredFeatures.insert(aCFeature); @@ -454,7 +493,8 @@ void findReferences(const std::set& theFeatures, } if (theUseRecursion) { #ifdef DEBUG_CYCLING_1550 - findReferences(aSelRefFeatures, theReferences, theUseComposite, theUseRecursion, theRecLevel); + findReferences(aSelRefFeatures, theReferences, theUseComposite, + theUseRecursion, theRecLevel); #else findReferences(theReferences[aFeature], theReferences, theUseComposite, theUseRecursion, theRecLevel); @@ -518,7 +558,8 @@ void findAllReferences(const std::set& theFeatures, std::cout << " Ref: " << getFeatureInfo(aFeature) << std::endl; #endif aRecLevel++; - addRefsToFeature(aFeature, aMainList, theReferences, aRecLevel, aResultRefList/*aMainRefList*/); + addRefsToFeature(aFeature, aMainList, theReferences, + aRecLevel, aResultRefList/*aMainRefList*/); } theReferences[aMainListFeature] = aResultRefList; } @@ -545,7 +586,8 @@ void findRefsToFeatures(const std::set& theFeatures, std::set::const_iterator aRefIt = aRefList.begin(), aRefLast = aRefList.end(); for (; aRefIt != aRefLast; aRefIt++) { FeaturePtr aRefFeature = *aRefIt; - CompositeFeaturePtr aComposite = std::dynamic_pointer_cast(aRefFeature); + CompositeFeaturePtr aComposite = + std::dynamic_pointer_cast(aRefFeature); if (aComposite.get() && aComposite->isSub(aFeature)) continue; /// composite of the current feature should not be removed @@ -583,4 +625,114 @@ void getConcealedResults(const FeaturePtr& theFeature, } } +std::pair getDefaultName( + const std::shared_ptr& theResult, + const int theResultIndex) +{ + 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) { + // 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); + return std::pair(aDefaultName.str(), false); + } + + 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; + } + } + + // find an object which is concealed by theResult + if (aFoundRef != aReferences.end() && !aFoundRef->second.empty()) { + // store number of references for each object + std::map aNbRefToObject; + // search the object by result index + std::list::const_iterator anObjIt = aFoundRef->second.begin(); + int aResultIndex = theResultIndex; + while (--aResultIndex >= 0) { + ResultPtr aCurRes = std::dynamic_pointer_cast(*anObjIt); + ResultCompSolidPtr aParentCompSolid = ModelAPI_Tools::compSolidOwner(aCurRes); + if (aParentCompSolid) + aCurRes = aParentCompSolid; + if (aNbRefToObject.find(aCurRes) == aNbRefToObject.end()) + aNbRefToObject[aCurRes] = 1; + else + aNbRefToObject[aCurRes] += 1; + + ++anObjIt; + if (anObjIt == aFoundRef->second.end()) { + anObjIt = aFoundRef->second.begin(); + break; + } + } + // check the result is a Body + 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; + + // return name of reference result only if it has been renamed by the user, + // in other case compose a default name + if (anObjRes->data()->hasUserDefinedName()) { + std::stringstream aName; + aName << anObjRes->data()->name(); + std::map::iterator aFound = aNbRefToObject.find(anObjRes); + if (aFound != aNbRefToObject.end()) { + // to generate unique name, add suffix if there are several results + // referring to the same shape + aName << "_" << aFound->second + 1; + } + return std::pair(aName.str(), true); + } + } + } + + // compose default name by the name of the feature and the index of result + std::stringstream aDefaultName; + 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; + return std::pair(aDefaultName.str(), false); +} + } // namespace ModelAPI_Tools