From: mpv Date: Tue, 2 Oct 2018 13:43:16 +0000 (+0300) Subject: Optimization for the model from the issue #2659 : X-Git-Tag: CEA_2018-2~31 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=bc788e781735676ab72fcf40219fe0e6e82cd0bc;p=modules%2Fshaper.git Optimization for the model from the issue #2659 : - cash history information for big amount of sub-shapes - use direct method of result parent checking instead of iteration of all results in hasObjects - remove checking of self-intersection: too slow for big models --- diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.cpp index 916feb814..6ed3adf8e 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.cpp @@ -30,12 +30,29 @@ #include #include #include +#include +#include + +// new shape -> old shapes -> index in the old shape +typedef NCollection_DataMap, TopTools_ShapeMapHasher> + MapNewToOld; +typedef + NCollection_DataMap > + HistoryMap; //================================================================================================= GeomAlgoAPI_MakeShape::GeomAlgoAPI_MakeShape() : myBuilderType(Unknown), myDone(false) { + myHist = 0; +} + +GeomAlgoAPI_MakeShape::~GeomAlgoAPI_MakeShape() { + if (myHist) { + delete (HistoryMap*)myHist; + } } //================================================================================================= @@ -220,6 +237,7 @@ void GeomAlgoAPI_MakeShape::initialize() { aCurrentShape->setImpl(new TopoDS_Shape(anExp.Current())); myMap->bind(aCurrentShape, aCurrentShape); } + myHist = 0; } @@ -260,3 +278,93 @@ bool GeomAlgoAPI_MakeShape::checkValid(std::string theMessage){ return true ; } +bool GeomAlgoAPI_MakeShape::newShapesCollected( + std::shared_ptr theWholeOld, const int theShapeType) +{ + if (!myHist) + return false; + HistoryMap* aHist = (HistoryMap*)myHist; + if (!aHist->IsBound(theShapeType)) + return false; + return aHist->Find(theShapeType).IsBound(theWholeOld->impl()); +} + +void GeomAlgoAPI_MakeShape::collectNewShapes( + std::shared_ptr theWholeOld, const int theShapeType) +{ + if (!myHist) + myHist = new HistoryMap; + HistoryMap* aHist = (HistoryMap*)myHist; + if (!aHist->IsBound(theShapeType)) + aHist->Bind( + theShapeType, NCollection_DataMap()); + aHist->ChangeFind(theShapeType). // add a new in anyway + Bind(theWholeOld->impl(), MapNewToOld()); + MapNewToOld& aCurrent = + aHist->ChangeFind(theShapeType).ChangeFind(theWholeOld->impl()); + ListOfShape aNewList; + TopTools_MapOfShape aViewed; //avoid same shapes + GeomAPI_ShapeExplorer anExp(theWholeOld, GeomAPI_Shape::ShapeType(theShapeType)); + for(int anIndexInWholeOld = 0; anExp.more(); anExp.next(), anIndexInWholeOld++) { + if (!aViewed.Add(anExp.current()->impl())) + continue; + aNewList.clear(); + modified(anExp.current(), aNewList); + for(ListOfShape::iterator aNew = aNewList.begin(); aNew != aNewList.end(); aNew++) { + const TopoDS_Shape& aNewShape = (*aNew)->impl(); + if (!aCurrent.IsBound(aNewShape)) { + aCurrent.Bind( + aNewShape, NCollection_DataMap()); + } + aCurrent.ChangeFind(aNewShape).Bind(anExp.current()->impl(), anIndexInWholeOld); + } + } +} + +static void addAllSubs(const TopoDS_Shape& theNewShape, + MapNewToOld& theCurrent, std::map& theResMap) +{ + if (theCurrent.IsBound(theNewShape)) { + NCollection_DataMap::Iterator + anOldIter(theCurrent.Find(theNewShape)); + for(; anOldIter.More(); anOldIter.Next()) { + theResMap[anOldIter.Value()] = anOldIter.Key(); + } + } + + TopoDS_Iterator anIter(theNewShape); + for(; anIter.More(); anIter.Next()) { + //if (anIter.Value().ShapeType() != TopAbs_VERTEX) + addAllSubs(anIter.Value(), theCurrent, theResMap); // add recursively + } +} + +std::shared_ptr GeomAlgoAPI_MakeShape::oldShapesForNew( + std::shared_ptr theWholeOld, + std::shared_ptr theNewShape, const int theShapeType) +{ + GeomShapePtr aResult(new GeomAPI_Shape); + TopoDS_Compound aResComp; + TopoDS_Builder aBuilder; + aBuilder.MakeCompound(aResComp); + aResult->setImpl(new TopoDS_Shape(aResComp)); + + HistoryMap* aHist = (HistoryMap*)myHist; + if (!aHist->IsBound(theShapeType)) + return aResult; // not found, empty compound + const TopoDS_Shape& aWholeOld = theWholeOld->impl(); + if (!aHist->Find(theShapeType).IsBound(aWholeOld)) + return aResult; // not found, empty compound + std::map aResMap; // map with all results, ordered by index in whole old + MapNewToOld& aCurrent = aHist->ChangeFind(theShapeType).ChangeFind(aWholeOld); + // we don't know what type of new shapes were produced by the old theShapeType, so, iterate all + addAllSubs(theNewShape->impl(), aCurrent, aResMap); + + std::map::iterator anOldIter = aResMap.begin(); + for(; anOldIter != aResMap.end(); anOldIter++) { + if (anOldIter->second.ShapeType() == (TopAbs_ShapeEnum)theShapeType) + aBuilder.Add(aResComp, anOldIter->second); + } + aResult->setImpl(new TopoDS_Shape(aResComp)); + return aResult; +} diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.h b/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.h index 6ed4f1d85..eb2396c96 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.h @@ -46,6 +46,9 @@ public: /// \brief Empty constructor. GEOMALGOAPI_EXPORT GeomAlgoAPI_MakeShape(); + /// Destructor for remove myHist + GEOMALGOAPI_EXPORT ~GeomAlgoAPI_MakeShape(); + /// \brief Constructor by builder and builder type. /// \param[in] theBuilder pointer to the builder. /// \param[in] theBuilderType builder type. @@ -115,6 +118,29 @@ public: /// \brief Check the validity of the produced shape. GEOMALGOAPI_EXPORT bool checkValid(std::string theMessage); + /// Optimization of access the new shapes by old shapes for the limited set of needed new shapes. + /// \param theWholeOld the whole old shape + /// \param theShapeType type of the sub-shapes that is used for optimization + /// \returns true if optimization containers are already filled + GEOMALGOAPI_EXPORT bool newShapesCollected( + std::shared_ptr theWholeOld, const int theShapeType); + + /// Optimization of access the new shapes by old shapes for the limited set of needed new shapes. + /// \param theWholeOld the whole old shape + /// \param theShapeType type of the sub-shapes that is used for optimization + /// \returns true if optimization containers are already filled + GEOMALGOAPI_EXPORT void collectNewShapes( + std::shared_ptr theWholeOld, const int theShapeType); + + /// Optimization of access the new shapes by old shapes for the limited set of needed new shapes. + /// \param theWholeOld the whole old shape + /// \param theNewShape the whole new shape + /// \param theShapeType type of the old sub-shapes + /// \returns compound of all old shapes that were used for creation of the given new + GEOMALGOAPI_EXPORT std::shared_ptr oldShapesForNew( + std::shared_ptr theWholeOld, + std::shared_ptr theNewShape, const int theShapeType); + protected: /// \brief Sets builder type. /// \param[in] theBuilderType new builder type. @@ -144,6 +170,10 @@ private: GeomAlgoAPI_MakeShape::BuilderType myBuilderType; ///< Type of make shape builder. bool myDone; ///< Builder status. std::shared_ptr myShape; ///< Resulting shape. + + /// map that is used to keep the optimization structure for access to the history + /// kind of sub-shapes -> whole old shape -> new shape -> list of old shapes that create this new + void* myHist; }; typedef std::list > ListOfMakeShape; diff --git a/src/GeomValidators/GeomValidators_NotSelfIntersected.cpp b/src/GeomValidators/GeomValidators_NotSelfIntersected.cpp index 7ab81f26c..aa017935d 100644 --- a/src/GeomValidators/GeomValidators_NotSelfIntersected.cpp +++ b/src/GeomValidators/GeomValidators_NotSelfIntersected.cpp @@ -74,10 +74,10 @@ bool GeomValidators_NotSelfIntersected::isValid(const std::shared_ptrisSelfIntersected(4)) { + /* optimization if (aShape->isSelfIntersected(4)) { theError = "Error: One of selected shapes are self-intersected."; return false; - } + }*/ } } else { theError = std::string("Error: validator does not support attribute with type: ") diff --git a/src/Model/Model_ResultBody.cpp b/src/Model/Model_ResultBody.cpp index 9b3401290..eaee3ac1e 100644 --- a/src/Model/Model_ResultBody.cpp +++ b/src/Model/Model_ResultBody.cpp @@ -53,13 +53,16 @@ Model_ResultBody::~Model_ResultBody() } void Model_ResultBody::loadAndOrientModifiedShapes(GeomAlgoAPI_MakeShape* theMS, - std::shared_ptr theShapeIn, const int theKindOfShape, const int theTag, + std::shared_ptr theShapeIn, const int theKindOfShape, const int theTag, const std::string& theName, GeomAPI_DataMapOfShapeShape& theSubShapes, const bool theIsStoreSeparate, const bool theIsStoreAsGenerated, const bool theSplitInSubs) { if (theSplitInSubs && mySubs.size()) { // consists of subs + // optimization of getting of new shapes for specific sub-result + if (!theMS->newShapesCollected(theShapeIn, theKindOfShape)) + theMS->collectNewShapes(theShapeIn, theKindOfShape); std::vector::const_iterator aSubIter = mySubs.cbegin(); for(; aSubIter != mySubs.cend(); aSubIter++) { // check that sub-shape was also created as modification of ShapeIn diff --git a/src/ModuleBase/ModuleBase_OperationFeature.cpp b/src/ModuleBase/ModuleBase_OperationFeature.cpp index b7b72a47b..04edf7957 100755 --- a/src/ModuleBase/ModuleBase_OperationFeature.cpp +++ b/src/ModuleBase/ModuleBase_OperationFeature.cpp @@ -206,13 +206,9 @@ bool ModuleBase_OperationFeature::hasObject(ObjectPtr theObj) const if (aFeature) { if (aFeature == theObj) return true; - std::list aResults; - ModelAPI_Tools::allResults(aFeature, aResults); - std::list::const_iterator aIt; - for (aIt = aResults.cbegin(); aIt != aResults.cend(); ++aIt) { - ResultPtr aResult = *aIt; - if (theObj == aResult) - return true; + ResultPtr anObjRes = std::dynamic_pointer_cast(theObj); + if (anObjRes.get() && aFeature == aFeature->document()->feature(anObjRes)) { + return true; } #ifdef DEBUG_DO_NOT_ACTIVATE_SUB_FEATURE if (aFeature->isMacro()) {