]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Fix for the issue #686: now compounds produced by the Boolean operations can be corre...
authormpv <mpv@opencascade.com>
Thu, 25 Jun 2015 13:22:25 +0000 (16:22 +0300)
committermpv <mpv@opencascade.com>
Thu, 25 Jun 2015 13:22:25 +0000 (16:22 +0300)
src/FeaturesPlugin/FeaturesPlugin_Boolean.cpp
src/Model/Model_ResultBody.cpp
src/Model/Model_ResultBody.h
src/Model/Model_ResultPart.cpp
src/Model/Model_ResultPart.h
src/Model/Model_Session.cpp
src/ModelAPI/ModelAPI_ResultBody.h
src/ModelAPI/ModelAPI_Tools.cpp
src/ModelAPI/ModelAPI_Tools.h
src/PartSet/PartSet_MenuMgr.cpp
src/PartSetPlugin/PartSetPlugin_Remove.cpp

index 1593759e94b007d2837845701bc0fb0ea4b508fd..bfb8655f400137167bffbb331412d2ac71297489 100644 (file)
@@ -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<ModelAPI_ResultBody> 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();
 
index f7492cc9534cfb7d71a92083b6e66dfefe547a3e..8cecd4a92d837d8ed336dba3218e673456270b35 100644 (file)
@@ -187,7 +187,7 @@ void Model_ResultBody::storeGenerated(const std::shared_ptr<GeomAPI_Shape>& theF
 }
 
 void Model_ResultBody::storeModified(const std::shared_ptr<GeomAPI_Shape>& theOldShape,
-  const std::shared_ptr<GeomAPI_Shape>& theNewShape)
+  const std::shared_ptr<GeomAPI_Shape>& theNewShape, const int theDecomposeSolidsTag)
 {
   std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(data());
   if (aData) {
@@ -205,6 +205,31 @@ void Model_ResultBody::storeModified(const std::shared_ptr<GeomAPI_Shape>& 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<Model_Document> aDoc = 
+            std::dynamic_pointer_cast<Model_Document>(document());
+          aDoc->addNamingName(aSubBuilder.NamedShape()->Label(), aSolidName);
+          TDataStd_Name::Set(aSubBuilder.NamedShape()->Label(), aSolidName.c_str());
+        }
+      }
+    }
   }
 }
 
index cafa565177122830702734ba0065bc4ec5d9a87f..75f9863f1896faf434f4193ca954380f6b84cbaf 100644 (file)
@@ -56,8 +56,13 @@ public:
                                               const std::shared_ptr<GeomAPI_Shape>& 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<GeomAPI_Shape>& theOldShape,
-                                              const std::shared_ptr<GeomAPI_Shape>& theNewShape);
+                                               const std::shared_ptr<GeomAPI_Shape>& theNewShape,
+                                          const int theDecomposeSolidsTag = 0);
 
   /// Returns the shape-result produced by this feature
   MODEL_EXPORT virtual std::shared_ptr<GeomAPI_Shape> shape();
index cd60eb2a6007a66cf45c945d210fb706b884b93c..dfd8c85949c0756870bc22422489135182774dd2 100644 (file)
@@ -8,6 +8,7 @@
 #include <ModelAPI_Data.h>
 #include <ModelAPI_AttributeDocRef.h>
 #include <ModelAPI_Session.h>
+#include <ModelAPI_Feature.h>
 
 std::shared_ptr<ModelAPI_Document> 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<ModelAPI_AttributeDocRef> aDocRef = data()->document(DOC_REF());
   return aDocRef->value().get();
 }
+
+bool Model_ResultPart::setDisabled(std::shared_ptr<ModelAPI_Result> 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<ModelAPI_Feature>(aDoc->object(
+          ModelAPI_Feature::group(), aDoc->size(ModelAPI_Feature::group()) - 1));
+        aDoc->setCurrentFeature(aLastFeature, false);
+      }
+    }
+    return true;
+  }
+  return false;
+}
index 7ebafd3ea0b22237d2b7e7ed10b3757a35fe0bc6..c2c70d94081377e47d23c755112085abff0ba983 100644 (file)
@@ -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<ModelAPI_Result> theThis,
+    const bool theFlag);
+
 protected:
   /// makes a result on a temporary feature (an action)
   Model_ResultPart();
index 04229f2c2257af2b46404547d8a463d4c23fe384..042ebe6f3964ec88c3a1d6a44b544fe6f2f43651 100644 (file)
@@ -22,6 +22,7 @@
 #include <Config_ModuleReader.h>
 #include <Config_ValidatorReader.h>
 #include <ModelAPI_ResultPart.h>
+#include <ModelAPI_Tools.h>
 
 #include <TDF_CopyTool.hxx>
 #include <TDF_DataSet.hxx>
@@ -205,10 +206,20 @@ std::shared_ptr<ModelAPI_Document> Model_Session::activeDocument()
   return myCurrentDoc;
 }
 
+/// makes the last feature in the document as the current
+static void makeCurrentLast(std::shared_ptr<ModelAPI_Document> theDoc) {
+  if (theDoc.get()) {
+    FeaturePtr aLastFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theDoc->object(
+      ModelAPI_Feature::group(), theDoc->size(ModelAPI_Feature::group()) - 1));
+    theDoc->setCurrentFeature(aLastFeature, false);
+  }
+}
+
 void Model_Session::setActiveDocument(
   std::shared_ptr<ModelAPI_Document> theDoc, bool theSendSignal)
 {
   if (myCurrentDoc != theDoc) {
+    std::shared_ptr<ModelAPI_Document> 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<Events_Message>& theMessa
       std::shared_ptr<ModelAPI_ObjectDeletedMessage> aDeleted =
         std::dynamic_pointer_cast<ModelAPI_ObjectDeletedMessage>(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());
       }
index ff4ce6e19819729ac8efc67b8e1a83a5194c7ea9..fb5751938d5ecaace295369f6d812979e749beb5 100644 (file)
@@ -45,7 +45,8 @@ public:
 
   /// Stores the modified shape (called by the execution method).
   virtual void storeModified(const std::shared_ptr<GeomAPI_Shape>& theOldShape,
-                                 const std::shared_ptr<GeomAPI_Shape>& theNewShape) = 0;
+                                 const std::shared_ptr<GeomAPI_Shape>& 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.
index 3a16235768086f153cbd7a827527520778865a89..cbe1290a852b80cc4192d1d38bf6889517a4a74f 100644 (file)
@@ -10,7 +10,8 @@
 #include <ModelAPI_Object.h>
 #include <ModelAPI_AttributeDouble.h>
 #include <ModelAPI_ResultParameter.h>
-
+#include <ModelAPI_ResultPart.h>
+#include <ModelAPI_AttributeDocRef.h>
 #include <list>
 #include <map>
 
@@ -153,4 +154,16 @@ void findRandomColor(std::vector<int>& 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<ModelAPI_ResultPart>(
+        theMain->object(ModelAPI_ResultPart::group(), a));
+    if (aPart && aPart->data()->document(ModelAPI_ResultPart::DOC_REF())->value() == theSub) {
+      return aPart;
+    }
+  }
+  return ResultPtr();
+}
+
 } // namespace ModelAPI_Tools
index 9bea2d9cd4ea7f1f3174e4e1af061c69498401d4..15f4afc1d6bb022bc3dcd3336bcfe9d8d878a260 100644 (file)
@@ -10,6 +10,8 @@
 #include "ModelAPI.h"
 #include <ModelAPI_Result.h>
 #include <ModelAPI_ResultParameter.h>
+#include <ModelAPI_Document.h>
+#include <ModelAPI_Feature.h>
 #include <GeomAPI_Shape.h>
 
 #include <vector>
@@ -32,6 +34,14 @@ MODELAPI_EXPORT bool findVariable(const std::string& theName, double& outValue,
  */
 MODELAPI_EXPORT void findRandomColor(std::vector<int>& 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
index 744b9b4f0c6d3ba1c155d2bddf926eeadff8c261..3163169774391d660c1eca14389ec851d2c37f9b 100644 (file)
@@ -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)
index 56881ca51238c578361d7126271ac2b3127684bb..d74666a65b208b0ee6bee701ff630f5e2942fd6d 100644 (file)
 #include <ModelAPI_ResultPart.h>
 #include <ModelAPI_Session.h>
 #include <ModelAPI_Feature.h>
+#include <ModelAPI_Tools.h>
 
 void PartSetPlugin_Remove::execute()
 {
   std::shared_ptr<ModelAPI_Session> aPManager = ModelAPI_Session::get();
   std::shared_ptr<ModelAPI_Document> aRoot = aPManager->moduleDocument();
-  std::shared_ptr<PartSetPlugin_Part> a;
-  for (int a = aRoot->size(ModelAPI_ResultPart::group()) - 1; a >= 0; a--) {
-    ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(
-        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<std::shared_ptr<ModelAPI_Feature> > 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<std::shared_ptr<ModelAPI_Feature> > aRefFeatures;
+      aRoot->refsToFeature(aFeature, aRefFeatures);
+      if (aRefFeatures.empty())
+        aRoot->removeFeature(aFeature);
     }
   }
 }