Salome HOME
Fix for the problem of update of the selection attribute value after it becomes inval...
[modules/shaper.git] / src / Model / Model_ResultConstruction.cpp
index a5230dd33fac08b7429bf882be57fcb3d1662e6f..a0c8a519b703a5ad4640a088b4e23d016fb1bf2e 100644 (file)
@@ -111,6 +111,21 @@ int Model_ResultConstruction::facesNum()
       }
     }
     myFacesUpToDate = true;
+
+    // update all the faces and sub-elements in the naming structure
+    DocumentPtr anEmptyExt;
+    bool aNotExt = false;
+    TDF_Label aDataLab = startLabel(anEmptyExt, aNotExt);
+    TDF_ChildIterator aSubsIter(aDataLab, Standard_False);
+    for(; aSubsIter.More(); aSubsIter.Next()) {
+      const TDF_Label aLab = aSubsIter.Value();
+      if (aLab.Tag() == 1) // skip the root shape label
+        continue;
+      Handle(TNaming_NamedShape) aNS;
+      if (aLab.FindAttribute(TNaming_NamedShape::GetID(), aNS)) {
+        update(aLab.Tag() - 1, anEmptyExt, aNotExt);
+      }
+    }
   }
   return int(myFaces.size());
 }
@@ -132,7 +147,7 @@ void Model_ResultConstruction::setInfinite(const bool theInfinite)
 
 void Model_ResultConstruction::setIsConcealed(const bool theValue)
 {
-  // do nothing: the construction element is never consealed
+  // do nothing: the construction element is never concealed
 }
 
 static const int kSTART_VERTEX_DELTA = 1000000;
@@ -473,8 +488,9 @@ int Model_ResultConstruction::select(const std::shared_ptr<GeomAPI_Shape>& theSu
   // iterate and store the result ids of sub-elements and sub-elements to sub-labels
   Handle(TDataStd_IntPackedMap) aRefs = TDataStd_IntPackedMap::Set(aLab);
   const int aSubNum = aComposite->numberOfSubs();
-  // subs are placed one by one  because of #2248): sketch curve may produce several edges
-  int aSubLabId = 1;
+  // subs are placed on unique labels because of #2248: sketch curve may produce several edges,
+  // but #2401 - on stable labels
+  NCollection_Map<int> aUsedIDMap; // already used lab tags for placement of shapes
 
   for(int a = 0; a < aSubNum; a++) {
     FeaturePtr aSub = aComposite->subFeature(a);
@@ -504,11 +520,12 @@ int Model_ResultConstruction::select(const std::shared_ptr<GeomAPI_Shape>& theSu
                   Standard_Real aFirst, aLast;
                   Handle(Geom_Curve) aFaceCurve = BRep_Tool::Curve(anEdge, aFirst, aLast);
                   if (aFaceCurve == aCurve) {
+                    while(aUsedIDMap.Contains(anID))
+                      anID += 100000;
+                    aUsedIDMap.Add(anID);
                     TDF_Label aSubLab = aLab.FindChild(anID);
-                    TDF_Label aShapeSubLab = aLab.FindChild(aSubLabId++);
                     std::string aFullNameSub = fullName(aComposite, anEdge);
-                    saveSubName(aComposite,
-                      aShapeSubLab, isSelectionMode, anEdge, aMyDoc, aFullNameSub);
+                    saveSubName(aComposite, aSubLab, isSelectionMode, anEdge, aMyDoc, aFullNameSub);
 
                     int anOrient = Model_SelectionNaming::edgeOrientation(aSubShape, anEdge);
                     if (anOrient != 0) {
@@ -522,10 +539,12 @@ int Model_ResultConstruction::select(const std::shared_ptr<GeomAPI_Shape>& theSu
                 for(TopExp_Explorer anEdgeExp(aSubShape, TopAbs_VERTEX);
                       anEdgeExp.More(); anEdgeExp.Next()) {
                     TopoDS_Vertex aV = TopoDS::Vertex(anEdgeExp.Current());
-                    TDF_Label aShapeSubLab = aLab.FindChild(aSubLabId++);
+                    while(aUsedIDMap.Contains(anID))
+                      anID += 100000;
+                    aUsedIDMap.Add(anID);
+                    TDF_Label aSubLab = aLab.FindChild(anID);
                     std::string aFullNameSub = fullName(aComposite, aV);
-                    saveSubName(aComposite,
-                      aShapeSubLab, isSelectionMode, aV, aMyDoc, aFullNameSub);
+                    saveSubName(aComposite, aSubLab, isSelectionMode, aV, aMyDoc, aFullNameSub);
                 }
               }
             }
@@ -607,10 +626,30 @@ bool Model_ResultConstruction::update(const int theIndex,
       }
       return aRes;
     } else {
+      // check is this modified or not
+      std::shared_ptr<GeomAPI_Shape> aNewShape = shape();
+      TopoDS_Shape anOldSh;
+      Handle(TNaming_NamedShape) aNS;
+      if (aLab.FindAttribute(TNaming_NamedShape::GetID(), aNS)) {
+        anOldSh = aNS->Get();
+      }
+      if (aNewShape.get()) {
+        if (anOldSh.IsNull())
+          theModified = true;
+        else {
+          std::shared_ptr<GeomAPI_Shape> anOldShape(new GeomAPI_Shape);
+          anOldShape->setImpl<TopoDS_Shape>(new TopoDS_Shape(anOldSh));
+          theModified = !anOldShape->isEqual(aNewShape);
+        }
+      }
+      else if (!anOldSh.IsNull()) {
+        theModified = true;
+      }
+
       // For correct naming selection, put the shape into the naming structure.
       // It seems sub-shapes are not needed: only this shape is (and can be ) selected.
       TNaming_Builder aBuilder(aLab);
-      aBuilder.Generated(shape()->impl<TopoDS_Shape>());
+      aBuilder.Generated(aNewShape->impl<TopoDS_Shape>());
     }
     return shape() && !shape()->isNull();
   }
@@ -626,7 +665,7 @@ bool Model_ResultConstruction::update(const int theIndex,
     Handle(TDF_Reference) aRef;
     if (aLab.FindAttribute(TDF_Reference::GetID(), aRef)) {
       int aFaceIndex = aRef->Get().Tag();
-      // don't check selection ,since face may disappear, but the shape stays correct
+      // don't check selection since face may disappear, but the shape stays correct
       Model_ResultConstruction::update(aFaceIndex, theExtDoc, theModified);
     }
     // getting a type of selected shape