Salome HOME
Fix for the issue #2573: Wrong position of created part
authormpv <mpv@opencascade.com>
Fri, 24 Aug 2018 13:56:37 +0000 (16:56 +0300)
committermpv <mpv@opencascade.com>
Fri, 24 Aug 2018 13:56:54 +0000 (16:56 +0300)
src/Model/Model_AttributeSelection.cpp
src/Model/Model_BodyBuilder.cpp
src/Model/Model_Document.cpp
src/Model/Model_Document.h

index 9d9fbb97b93b6f5f9288e12d5b43045cfb19f4fc..b81952bd58d0d1b6188dc675235c27b9a59c054f 100644 (file)
@@ -180,6 +180,17 @@ bool Model_AttributeSelection::setValue(const ObjectPtr& theContext,
     aSelLab.ForgetAllAttributes(true);
     TDataStd_UAttribute::Set(aSelLab, kPART_REF_ID);
     selectPart(std::dynamic_pointer_cast<ModelAPI_Result>(theContext), theSubShape);
+  } else { // check the feature context: parent-Part of this feature should not be used
+    FeaturePtr aFeatureContext = std::dynamic_pointer_cast<ModelAPI_Feature>(theContext);
+    if (aFeatureContext.get()) {
+      if (owner()->document() != aFeatureContext->document()) {
+        aSelLab.ForgetAllAttributes(true);
+        myRef.setValue(ObjectPtr());
+        if (aToUnblock)
+          owner()->data()->blockSendAttributeUpdated(false);
+        return false;
+      }
+    }
   }
 
   owner()->data()->sendAttributeUpdated(this);
index c301d069454f987074caa7b9b4cc88d671837944..82f33b986f1a95cf388e48f8ad68796e4190272b 100755 (executable)
@@ -213,6 +213,18 @@ void Model_BodyBuilder::storeGenerated(const std::shared_ptr<GeomAPI_Shape>& the
   }
 }
 
+TNaming_Builder* Model_BodyBuilder::builder(const int theTag)
+{
+  std::map<int, TNaming_Builder*>::iterator aFind = myBuilders.find(theTag);
+  if (aFind == myBuilders.end()) {
+    std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(data());
+    myBuilders[theTag] = new TNaming_Builder(
+      theTag == 0 ? aData->shapeLab() : aData->shapeLab().FindChild(theTag));
+    aFind = myBuilders.find(theTag);
+  }
+  return aFind->second;
+}
+
 void Model_BodyBuilder::storeModified(const std::shared_ptr<GeomAPI_Shape>& theOldShape,
   const std::shared_ptr<GeomAPI_Shape>& theNewShape, const int theDecomposeSolidsTag)
 {
@@ -223,7 +235,7 @@ void Model_BodyBuilder::storeModified(const std::shared_ptr<GeomAPI_Shape>& theO
     if (theDecomposeSolidsTag != -2)
       clean();
     // store the new shape as primitive
-    TNaming_Builder aBuilder(aShapeLab);
+    TNaming_Builder* aBuilder = builder(0);
     if (!theOldShape || !theNewShape)
       return;  // bad shape
     TopoDS_Shape aShapeOld = theOldShape->impl<TopoDS_Shape>();
@@ -232,15 +244,15 @@ void Model_BodyBuilder::storeModified(const std::shared_ptr<GeomAPI_Shape>& theO
     TopoDS_Shape aShapeNew = theNewShape->impl<TopoDS_Shape>();
     if (aShapeNew.IsNull())
       return;  // null shape inside
-    aBuilder.Modify(aShapeOld, aShapeNew);
-    if(!aBuilder.NamedShape()->IsEmpty()) {
+    aBuilder->Modify(aShapeOld, aShapeNew);
+    if(!aBuilder->NamedShape()->IsEmpty()) {
       Handle(TDataStd_Name) anAttr;
-      if(aBuilder.NamedShape()->Label().FindAttribute(TDataStd_Name::GetID(),anAttr)) {
+      if(aBuilder->NamedShape()->Label().FindAttribute(TDataStd_Name::GetID(),anAttr)) {
         std::string aName (TCollection_AsciiString(anAttr->Get()).ToCString());
         if(!aName.empty()) {
           std::shared_ptr<Model_Document> aDoc =
             std::dynamic_pointer_cast<Model_Document>(document());
-          aDoc->addNamingName(aBuilder.NamedShape()->Label(), aName);
+          aDoc->addNamingName(aBuilder->NamedShape()->Label(), aName);
         }
       }
     }
@@ -290,18 +302,6 @@ Model_BodyBuilder::~Model_BodyBuilder()
   clean();
 }
 
-TNaming_Builder* Model_BodyBuilder::builder(const int theTag)
-{
-  std::map<int, TNaming_Builder*>::iterator aFind = myBuilders.find(theTag);
-  if (aFind == myBuilders.end()) {
-    std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(data());
-    myBuilders[theTag] = new TNaming_Builder(
-      theTag == 0 ? aData->shapeLab() : aData->shapeLab().FindChild(theTag));
-    aFind = myBuilders.find(theTag);
-  }
-  return aFind->second;
-}
-
 void Model_BodyBuilder::buildName(const int theTag, const std::string& theName)
 {
   std::shared_ptr<Model_Document> aDoc = std::dynamic_pointer_cast<Model_Document>(document());
@@ -687,8 +687,18 @@ void Model_BodyBuilder::loadAndOrientModifiedShapes (
         // Store only in case if it does not have reference.
         if (!aShapeLab.FindAttribute(TDF_Reference::GetID(), aRef)) {
           if (theIsStoreAsGenerated) {
+            TNaming_Builder* aBuilder = builder(0);
+            if (!aBuilder->NamedShape().IsNull() &&
+                aBuilder->NamedShape()->Evolution() != TNaming_GENERATED) {
+              myBuilders.erase(0); // clear old builder to avoid different evolutions crash
+            }
             builder(0)->Generated(aRoot, aNewShape);
           } else {
+            TNaming_Builder* aBuilder = builder(0);
+            if (!aBuilder->NamedShape().IsNull() &&
+              aBuilder->NamedShape()->Evolution() != TNaming_MODIFY) {
+              myBuilders.erase(0); // clear old builder to avoid different evolutions crash
+            }
             builder(0)->Modify(aRoot, aNewShape);
           }
         }
index caba9de1337b13ec201b8b6032512169212f07d7..22cc823d05e7e8c495e8a12198b3791ceee7900f 100755 (executable)
@@ -91,7 +91,7 @@ static const int TAG_NODES_STATE = 4; ///< array, tag of the Object Browser node
 static const int TAG_EXTERNAL_CONSTRUCTIONS = 5;
 
 Model_Document::Model_Document(const int theID, const std::string theKind)
-    : myID(theID), myKind(theKind), myIsActive(false),
+    : myID(theID), myKind(theKind), myIsActive(false), myIsSetCurrentFeature(false),
       myDoc(new TDocStd_Document("BinOcaf"))  // binary OCAF format
 {
 #ifdef TINSPECTOR
@@ -1084,6 +1084,9 @@ std::shared_ptr<ModelAPI_Feature> Model_Document::currentFeature(const bool theV
 void Model_Document::setCurrentFeature(
   std::shared_ptr<ModelAPI_Feature> theCurrent, const bool theVisible)
 {
+  if (myIsSetCurrentFeature)
+    return;
+  myIsSetCurrentFeature = true;
   // blocks the flush signals to avoid each objects visualization in the viewer
   // they should not be shown once after all modifications are performed
   Events_Loop* aLoop = Events_Loop::loop();
@@ -1120,6 +1123,7 @@ void Model_Document::setCurrentFeature(
     std::shared_ptr<Model_Data> aData = std::static_pointer_cast<Model_Data>(theCurrent->data());
     if (!aData.get() || !aData->isValid()) {
       aLoop->activateFlushes(isActive);
+      myIsSetCurrentFeature = false;
       return;
     }
     TDF_Label aFeatureLabel = aData->label().Father();
@@ -1192,6 +1196,7 @@ void Model_Document::setCurrentFeature(
       }
     }
   }
+  myIsSetCurrentFeature = false;
   // unblock  the flush signals and up them after this
   aLoop->activateFlushes(isActive);
 }
index 98c44ea64b94944a02f6559399926036b3305220..e40b2e928a1a87143aa2eb78c52bfc13978797d5 100644 (file)
@@ -430,6 +430,8 @@ class Model_Document : public ModelAPI_Document
 
   //! The selection feature, if needed
   FeaturePtr mySelectionFeature;
+
+  bool myIsSetCurrentFeature; ///< flag that my current feature is changed right now (recursion)
 };
 
 #endif