From 1b6e16d96b4f83c138791e0e86842d1507bcef1f Mon Sep 17 00:00:00 2001 From: mpv Date: Thu, 25 Jun 2015 16:22:25 +0300 Subject: [PATCH] Fix for the issue #686: now compounds produced by the Boolean operations can be correctly selected by the naming procedure --- src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp | 3 +- src/Model/Model_ResultBody.cpp | 27 ++++++++++++++- src/Model/Model_ResultBody.h | 7 +++- src/Model/Model_ResultPart.cpp | 29 ++++++++++++++++ src/Model/Model_ResultPart.h | 4 +++ src/Model/Model_Session.cpp | 33 ++++++++++++++++++- src/ModelAPI/ModelAPI_ResultBody.h | 3 +- src/ModelAPI/ModelAPI_Tools.cpp | 15 ++++++++- src/ModelAPI/ModelAPI_Tools.h | 10 ++++++ src/PartSet/PartSet_MenuMgr.cpp | 8 +++++ src/PartSetPlugin/PartSetPlugin_Remove.cpp | 26 +++++++-------- 11 files changed, 145 insertions(+), 20 deletions(-) diff --git a/src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp b/src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp index 1593759e9..bfb8655f4 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp @@ -20,6 +20,7 @@ #define FACE 4 #define _MODIFY_TAG 1 #define _DELETED_TAG 2 +#define _SUBSOLIDS_TAG 3 /// sub solids will be placed at labels 3, 4, etc. if result is compound of solids //================================================================================================= FeaturesPlugin_Boolean::FeaturesPlugin_Boolean() @@ -182,7 +183,7 @@ void FeaturesPlugin_Boolean::LoadNamingDS(std::shared_ptr t if(theBaseShape->isEqual(theAlgo.shape())) { theResultBody->store(theAlgo.shape()); } else { - theResultBody->storeModified(theBaseShape, theAlgo.shape()); + theResultBody->storeModified(theBaseShape, theAlgo.shape(), _SUBSOLIDS_TAG); GeomAPI_DataMapOfShapeShape* aSubShapes = new GeomAPI_DataMapOfShapeShape(); diff --git a/src/Model/Model_ResultBody.cpp b/src/Model/Model_ResultBody.cpp index f7492cc95..8cecd4a92 100644 --- a/src/Model/Model_ResultBody.cpp +++ b/src/Model/Model_ResultBody.cpp @@ -187,7 +187,7 @@ void Model_ResultBody::storeGenerated(const std::shared_ptr& theF } void Model_ResultBody::storeModified(const std::shared_ptr& theOldShape, - const std::shared_ptr& theNewShape) + const std::shared_ptr& theNewShape, const int theDecomposeSolidsTag) { std::shared_ptr aData = std::dynamic_pointer_cast(data()); if (aData) { @@ -205,6 +205,31 @@ void Model_ResultBody::storeModified(const std::shared_ptr& theOl if (aShapeNew.IsNull()) return; // null shape inside aBuilder.Modify(aShapeOld, aShapeNew); + if (theDecomposeSolidsTag && aShapeNew.ShapeType() == TopAbs_COMPOUND) { // make sub elements as subs + + // register name if it is possible + TCollection_AsciiString aName; + if(!aBuilder.NamedShape()->IsEmpty()) { + Handle(TDataStd_Name) anAttr; + if(aBuilder.NamedShape()->Label().FindAttribute(TDataStd_Name::GetID(),anAttr)) { + aName = TCollection_AsciiString(anAttr->Get()).ToCString(); + } + } + + TopoDS_Iterator aSubIter(aShapeNew); + for(int aTag = theDecomposeSolidsTag; aSubIter.More(); aSubIter.Next()) { + TNaming_Builder aSubBuilder(aShapeLab.FindChild(aTag++)); + aSubBuilder.Generated(aSubIter.Value()); + if(!aName.IsEmpty()) { + std::string aSolidName = + (aName + "_Solid_" + TCollection_AsciiString(aTag - theDecomposeSolidsTag)).ToCString(); + std::shared_ptr aDoc = + std::dynamic_pointer_cast(document()); + aDoc->addNamingName(aSubBuilder.NamedShape()->Label(), aSolidName); + TDataStd_Name::Set(aSubBuilder.NamedShape()->Label(), aSolidName.c_str()); + } + } + } } } diff --git a/src/Model/Model_ResultBody.h b/src/Model/Model_ResultBody.h index cafa56517..75f9863f1 100644 --- a/src/Model/Model_ResultBody.h +++ b/src/Model/Model_ResultBody.h @@ -56,8 +56,13 @@ public: const std::shared_ptr& theToShape); /// Stores the modified shape (called by the execution method). + /// \param theOldShape shape that produces result + /// \param theNewShape resulting shape + /// \param theDecomposeSolidsTag tag for starting of solids sub-elements placement in case + /// theNewShape is compound of solids, if zero it is not used MODEL_EXPORT virtual void storeModified(const std::shared_ptr& theOldShape, - const std::shared_ptr& theNewShape); + const std::shared_ptr& theNewShape, + const int theDecomposeSolidsTag = 0); /// Returns the shape-result produced by this feature MODEL_EXPORT virtual std::shared_ptr shape(); diff --git a/src/Model/Model_ResultPart.cpp b/src/Model/Model_ResultPart.cpp index cd60eb2a6..dfd8c8594 100644 --- a/src/Model/Model_ResultPart.cpp +++ b/src/Model/Model_ResultPart.cpp @@ -8,6 +8,7 @@ #include #include #include +#include std::shared_ptr Model_ResultPart::partDoc() { @@ -44,7 +45,16 @@ void Model_ResultPart::activate() } } if (aDocRef->value().get()) { + SessionPtr aMgr = ModelAPI_Session::get(); + bool isNewTransaction = !aMgr->isOperation(); + // activation may cause changes in current features in document, so it must be in transaction + if (isNewTransaction) { + aMgr->startOperation("Activation"); + } ModelAPI_Session::get()->setActiveDocument(aDocRef->value()); + if (isNewTransaction) { + aMgr->finishOperation(); + } } } @@ -53,3 +63,22 @@ bool Model_ResultPart::isActivated() std::shared_ptr aDocRef = data()->document(DOC_REF()); return aDocRef->value().get(); } + +bool Model_ResultPart::setDisabled(std::shared_ptr theThis, + const bool theFlag) +{ + if (ModelAPI_ResultPart::setDisabled(theThis, theFlag)) { + DocumentPtr aDoc = Model_ResultPart::partDoc(); + if (aDoc.get()) { + if (theFlag) { // disable, so make all features disabled too + aDoc->setCurrentFeature(FeaturePtr(), false); + } else { // enabled, so make the current feature the last inside of this document + FeaturePtr aLastFeature = std::dynamic_pointer_cast(aDoc->object( + ModelAPI_Feature::group(), aDoc->size(ModelAPI_Feature::group()) - 1)); + aDoc->setCurrentFeature(aLastFeature, false); + } + } + return true; + } + return false; +} diff --git a/src/Model/Model_ResultPart.h b/src/Model/Model_ResultPart.h index 7ebafd3ea..c2c70d940 100644 --- a/src/Model/Model_ResultPart.h +++ b/src/Model/Model_ResultPart.h @@ -28,6 +28,10 @@ class Model_ResultPart : public ModelAPI_ResultPart /// Sets this document as current and if it is not loaded yet, loads it MODEL_EXPORT virtual void activate(); + /// disable all feature of the part on disable of the part result + MODEL_EXPORT virtual bool setDisabled(std::shared_ptr theThis, + const bool theFlag); + protected: /// makes a result on a temporary feature (an action) Model_ResultPart(); diff --git a/src/Model/Model_Session.cpp b/src/Model/Model_Session.cpp index 04229f2c2..042ebe6f3 100644 --- a/src/Model/Model_Session.cpp +++ b/src/Model/Model_Session.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -205,10 +206,20 @@ std::shared_ptr Model_Session::activeDocument() return myCurrentDoc; } +/// makes the last feature in the document as the current +static void makeCurrentLast(std::shared_ptr theDoc) { + if (theDoc.get()) { + FeaturePtr aLastFeature = std::dynamic_pointer_cast(theDoc->object( + ModelAPI_Feature::group(), theDoc->size(ModelAPI_Feature::group()) - 1)); + theDoc->setCurrentFeature(aLastFeature, false); + } +} + void Model_Session::setActiveDocument( std::shared_ptr theDoc, bool theSendSignal) { if (myCurrentDoc != theDoc) { + std::shared_ptr aPrevious = myCurrentDoc; myCurrentDoc = theDoc; if (theDoc.get() && theSendSignal) { // syncronize the document: it may be just opened or opened but removed before @@ -224,6 +235,25 @@ void Model_Session::setActiveDocument( new Events_Message(Events_Loop::eventByName(EVENT_DOCUMENT_CHANGED))); Events_Loop::loop()->send(aMsg); } + // make the current state correct and synchronised in the module and sub-documents + if (isOperation()) { // do it only in transaction, not on opening of document + if (myCurrentDoc == moduleDocument()) { + // make the current feature the latest in root, in previous root current become also last + makeCurrentLast(aPrevious); + makeCurrentLast(myCurrentDoc); + } else { + // make the current feature the latest in sub, root current feature becomes this sub + makeCurrentLast(myCurrentDoc); + DocumentPtr aRoot = moduleDocument(); + ResultPtr aPartRes = ModelAPI_Tools::findPartResult(aRoot, myCurrentDoc); + if (aPartRes.get()) { + FeaturePtr aPartFeat = aRoot->feature(aPartRes); + if (aPartFeat.get()) { + aRoot->setCurrentFeature(aPartFeat, false); + } + } + } + } } } @@ -343,7 +373,8 @@ void Model_Session::processEvent(const std::shared_ptr& theMessa std::shared_ptr aDeleted = std::dynamic_pointer_cast(theMessage); if (aDeleted && - aDeleted->groups().find(ModelAPI_ResultPart::group()) != aDeleted->groups().end()) + aDeleted->groups().find(ModelAPI_ResultPart::group()) != aDeleted->groups().end() && + !ModelAPI_Tools::findPartResult(moduleDocument(), activeDocument()).get()) // another part may be disabled { setActiveDocument(moduleDocument()); } diff --git a/src/ModelAPI/ModelAPI_ResultBody.h b/src/ModelAPI/ModelAPI_ResultBody.h index ff4ce6e19..fb5751938 100644 --- a/src/ModelAPI/ModelAPI_ResultBody.h +++ b/src/ModelAPI/ModelAPI_ResultBody.h @@ -45,7 +45,8 @@ public: /// Stores the modified shape (called by the execution method). virtual void storeModified(const std::shared_ptr& theOldShape, - const std::shared_ptr& theNewShape) = 0; + const std::shared_ptr& theNewShape, + const int theDecomposeSolidsTag = 0) = 0; /// Records the subshape newShape which was generated during a topological construction. /// As an example, consider the case of a face generated in construction of a box. diff --git a/src/ModelAPI/ModelAPI_Tools.cpp b/src/ModelAPI/ModelAPI_Tools.cpp index 3a1623576..cbe1290a8 100644 --- a/src/ModelAPI/ModelAPI_Tools.cpp +++ b/src/ModelAPI/ModelAPI_Tools.cpp @@ -10,7 +10,8 @@ #include #include #include - +#include +#include #include #include @@ -153,4 +154,16 @@ void findRandomColor(std::vector& theValues) } } +ResultPtr findPartResult(const DocumentPtr& theMain, const DocumentPtr& 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)); + if (aPart && aPart->data()->document(ModelAPI_ResultPart::DOC_REF())->value() == theSub) { + return aPart; + } + } + return ResultPtr(); +} + } // namespace ModelAPI_Tools diff --git a/src/ModelAPI/ModelAPI_Tools.h b/src/ModelAPI/ModelAPI_Tools.h index 9bea2d9cd..15f4afc1d 100644 --- a/src/ModelAPI/ModelAPI_Tools.h +++ b/src/ModelAPI/ModelAPI_Tools.h @@ -10,6 +10,8 @@ #include "ModelAPI.h" #include #include +#include +#include #include #include @@ -32,6 +34,14 @@ MODELAPI_EXPORT bool findVariable(const std::string& theName, double& outValue, */ MODELAPI_EXPORT void findRandomColor(std::vector& theValues); +/*! + * Searches for Part result that contains the reference to the given document. + * \param theMain document that contains the searched feature + * \param theSub document that is searched, the resulting feature references to it + * \returns numm if not found + */ +MODELAPI_EXPORT ResultPtr findPartResult(const DocumentPtr& theMain, const DocumentPtr& theSub); + } #endif diff --git a/src/PartSet/PartSet_MenuMgr.cpp b/src/PartSet/PartSet_MenuMgr.cpp index 744b9b4f0..316316977 100644 --- a/src/PartSet/PartSet_MenuMgr.cpp +++ b/src/PartSet/PartSet_MenuMgr.cpp @@ -488,7 +488,15 @@ void PartSet_MenuMgr::onActivatePart(bool) void PartSet_MenuMgr::onActivatePartSet(bool) { SessionPtr aMgr = ModelAPI_Session::get(); + bool isNewTransaction = !aMgr->isOperation(); + // activation may cause changes in current features in document, so it must be in transaction + if (isNewTransaction) { + aMgr->startOperation("Activation"); + } aMgr->setActiveDocument(aMgr->moduleDocument()); + if (isNewTransaction) { + aMgr->finishOperation(); + } } void PartSet_MenuMgr::onEdit(bool) diff --git a/src/PartSetPlugin/PartSetPlugin_Remove.cpp b/src/PartSetPlugin/PartSetPlugin_Remove.cpp index 56881ca51..d74666a65 100644 --- a/src/PartSetPlugin/PartSetPlugin_Remove.cpp +++ b/src/PartSetPlugin/PartSetPlugin_Remove.cpp @@ -12,25 +12,23 @@ #include #include #include +#include void PartSetPlugin_Remove::execute() { std::shared_ptr aPManager = ModelAPI_Session::get(); std::shared_ptr aRoot = aPManager->moduleDocument(); - std::shared_ptr a; - for (int a = aRoot->size(ModelAPI_ResultPart::group()) - 1; a >= 0; a--) { - ResultPartPtr aPart = std::dynamic_pointer_cast( - aRoot->object(ModelAPI_ResultPart::group(), a)); - if (aPart && aPart->data()->document(ModelAPI_ResultPart::DOC_REF())->value() == document()) { - FeaturePtr aFeature = aRoot->feature(aPart); - if (aFeature) { - // do remove - aPart->data()->document(ModelAPI_ResultPart::DOC_REF())->value()->close(); - std::set > aRefFeatures; - aRoot->refsToFeature(aFeature, aRefFeatures); - if (aRefFeatures.empty()) - aRoot->removeFeature(aFeature); - } + DocumentPtr aThisDoc = document(); + ResultPtr aPart = ModelAPI_Tools::findPartResult(aRoot, aThisDoc); + if (aPart.get()) { + FeaturePtr aFeature = aRoot->feature(aPart); + if (aFeature) { + // do remove + aPart->data()->document(ModelAPI_ResultPart::DOC_REF())->value()->close(); + std::set > aRefFeatures; + aRoot->refsToFeature(aFeature, aRefFeatures); + if (aRefFeatures.empty()) + aRoot->removeFeature(aFeature); } } } -- 2.30.2