]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Issue #19058: Error in sketch projection when changing parameter
authorArtem Zhidkov <Artem.Zhidkov@opencascade.com>
Sat, 9 May 2020 19:57:55 +0000 (22:57 +0300)
committerArtem Zhidkov <Artem.Zhidkov@opencascade.com>
Sun, 10 May 2020 09:10:09 +0000 (12:10 +0300)
Provide the backward compatibility of selection mechanism.

src/Selector/Selector_Algo.cpp
src/Selector/Selector_Algo.h
src/Selector/Selector_Intersect.cpp
src/Selector/Selector_Intersect.h
src/Selector/Selector_Modify.cpp
src/Selector/Selector_Modify.h
src/Selector/Selector_NExplode.cpp
src/Selector/Selector_NExplode.h
src/Selector/Selector_WeakName.cpp
src/Selector/Selector_WeakName.h

index 4a186b67b3b84dff54240e76d38ea1d900402c3a..a21be5fa5dac83eb8cb6cc3e33aa24765bf4b2d8 100644 (file)
@@ -431,7 +431,8 @@ Selector_Algo* Selector_Algo::restoreByName(TDF_Label theLab, TDF_Label theBaseD
     }
   } else if (theName[0] == '(') { // filter by neighbors
     aResult = new Selector_FilterByNeighbors;
-  } else if (theName.find(pureWeakNameID()) == 0) { // weak naming identifier
+  } else if (theName.find(pureWeakNameID()) == 0 ||
+             theName.find(oldPureWeakNameID()) == 0) { // weak naming identifier
     aResult = new Selector_WeakName;
   } else if (theName.find('&') != std::string::npos) { // modification
     aResult = new Selector_Modify;
index 5a21a75447d23f8e728c2d6ee32466493c7c456e..a946a1c833171743883a7f77487dfc53a89425b1 100644 (file)
@@ -148,16 +148,28 @@ protected:
     static const Standard_GUID kSHAPE_TYPE("864b3267-cb9d-4107-bf58-c3ce1775b171");
     return kSHAPE_TYPE;
   }
+  /// old string identifier of the weak name in modification or intersection types of algorithm
+  static const std::string& oldWeakNameID()
+  {
+    static const std::string kWEAK_NAME_IDENTIFIER = "weak_name_";
+    return kWEAK_NAME_IDENTIFIER;
+  }
+  /// old string identifier of the pure weak name
+  static const std::string& oldPureWeakNameID()
+  {
+    static const std::string kPURE_WEAK_NAME_IDENTIFIER = "_weak_name_";
+    return kPURE_WEAK_NAME_IDENTIFIER;
+  }
   /// string identifier of the weak name in modification or intersection types of algorithm
   static const std::string& weakNameID()
   {
-    static const std::string kWEAK_NAME_IDENTIFIER = "weak_name_";
+    static const std::string kWEAK_NAME_IDENTIFIER = std::string("new_") + oldWeakNameID();
     return kWEAK_NAME_IDENTIFIER;
   }
   /// string identifier of the pure weak name
   static const std::string& pureWeakNameID()
   {
-    static const std::string kPURE_WEAK_NAME_IDENTIFIER = "_weak_name_";
+    static const std::string kPURE_WEAK_NAME_IDENTIFIER = std::string("_new") + oldPureWeakNameID();
     return kPURE_WEAK_NAME_IDENTIFIER;
   }
   /// Stores the type of an algorithm in the data tree (in myLab)
index e473bb69755c3008f5eb78a0afdee1b1a6a1ca62..a104911deff98d68d6263feda3a8c64bfd91f018 100644 (file)
@@ -36,6 +36,7 @@
 Selector_Intersect::Selector_Intersect() : Selector_AlgoWithSubs()
 {
   myWeakIndex = -1; // no index by default
+  myRecomputeWeakIndex = false;
 }
 
 // returns the sub-shapes of theSubType which belong to all theShapes (so, common or intersection)
@@ -190,9 +191,14 @@ TDF_Label Selector_Intersect::restoreByName(std::string theName,
     size_t anEndPos = theName.find(']', aStart + 1);
     if (anEndPos != std::string::npos) {
       std::string aSubStr = theName.substr(aStart + 1, anEndPos - aStart - 1);
-      if (aSubStr.find(weakNameID()) == 0) { // weak name identifier
-        std::string aWeakIndex = aSubStr.substr(weakNameID().size());
+      size_t aFoundOldWeak = aSubStr.find(oldWeakNameID());
+      size_t aFoundNewWeak = aFoundOldWeak != std::string::npos ?
+                             aSubStr.find(weakNameID()) :
+                             aFoundOldWeak;
+      if (aFoundOldWeak == 0 || aFoundNewWeak == 0) { // weak name identifier
+        std::string aWeakIndex = aSubStr.substr(aFoundOldWeak + oldWeakNameID().size());
         myWeakIndex = atoi(aWeakIndex.c_str());
+        myRecomputeWeakIndex = aFoundOldWeak == 0;
         continue;
       }
       TopAbs_ShapeEnum aSubShapeType = TopAbs_FACE;
@@ -245,8 +251,9 @@ bool Selector_Intersect::solve(const TopoDS_Shape& theContext)
   commonShapes(aSubSelectorShapes, myShapeType, aCommon);
   if (aCommon.Extent() != 1) {
     if (myWeakIndex != -1) {
-      Selector_NExplode aNexp(aCommon);
+      Selector_NExplode aNexp(aCommon, myRecomputeWeakIndex);
       aResult = aNexp.shape(myWeakIndex);
+      myRecomputeWeakIndex = false;
     } else if (geometricalNaming() && aCommon.Extent() > 1) {
       // check results are on the same geometry, create compound
       TopoDS_ListOfShape::Iterator aCommonIter(aCommon);
index 52a9b89a4145209f3afa6fe6db9243c9a13962f8..1df1326c68e0c8fadfdd2a2ae3833e5e9a66ee84 100644 (file)
@@ -32,6 +32,7 @@ class Selector_Intersect: public Selector_AlgoWithSubs
 {
   TopAbs_ShapeEnum myShapeType; ///< type of this shape
   int myWeakIndex; ///< weak index in case intersection produces several shapes
+  bool myRecomputeWeakIndex; ///< if the index is stored with old (unstable) order, recompute it
 public:
   /// Initializes the selection of this kind
   SELECTOR_EXPORT bool select(const TopoDS_Shape theContext, const TopoDS_Shape theValue);
index 4b719df2ce26c0113609ddd7d53cafb0b6c3f673..eb0817d835d1ea815c952294fa5cbb3b1bce203e 100644 (file)
@@ -40,6 +40,7 @@
 Selector_Modify::Selector_Modify() : Selector_Algo()
 {
   myWeakIndex = -1; // no index by default
+  myRecomputeWeakIndex = false;
 }
 
 // adds to theResult all labels that contain initial shapes for theValue located in theFinal
@@ -253,9 +254,13 @@ TDF_Label Selector_Modify::restoreByName(std::string theName,
     anEnd = theName.find('&', aStart);
     std::string aSubStr =
       theName.substr(aStart, anEnd == std::string::npos ? anEnd : anEnd - aStart);
-    if (aSubStr.find(weakNameID()) == 0) { // weak name identifier
-      std::string aWeakIndex = aSubStr.substr(weakNameID().size());
-      myWeakIndex = atoi(aWeakIndex.c_str());
+    size_t aFoundOldWeak = aSubStr.find(oldWeakNameID());
+    size_t aFoundNewWeak = aFoundOldWeak != std::string::npos ?
+                           aSubStr.find(weakNameID()) :
+                           aFoundOldWeak;
+    if (aFoundOldWeak == 0 || aFoundNewWeak == 0) { // weak name identifier
+      std::string aWeakIndex = aSubStr.substr(aFoundOldWeak + oldWeakNameID().size());\r      myWeakIndex = atoi(aWeakIndex.c_str());
+      myRecomputeWeakIndex = aFoundOldWeak == 0;
       continue;
     }
     TDF_Label aSubContext, aValue;
@@ -310,8 +315,9 @@ bool Selector_Modify::solve(const TopoDS_Shape& theContext)
           aCommon.Append(aNewShape);
       }
     }
-    Selector_NExplode aNexp(aCommon);
+    Selector_NExplode aNexp(aCommon, myRecomputeWeakIndex);
     aResult = aNexp.shape(myWeakIndex);
+    myRecomputeWeakIndex = false;
   } else { // standard case
     TopoDS_ListOfShape aFinalsCommon; // final shapes presented in all results from bases
     findModificationResult(aFinalsCommon);
@@ -319,8 +325,9 @@ bool Selector_Modify::solve(const TopoDS_Shape& theContext)
       aResult = aFinalsCommon.First();
       findNewVersion(theContext, aResult);
     } else if (aFinalsCommon.Extent() > 1 && myWeakIndex > 0) {
-      Selector_NExplode aNExp(aFinalsCommon);
+      Selector_NExplode aNExp(aFinalsCommon, myRecomputeWeakIndex);
       aResult = aNExp.shape(myWeakIndex);
+      myRecomputeWeakIndex = false;
       findNewVersion(theContext, aResult);
     } else if (aFinalsCommon.Extent() > 1 && geometricalNaming()) {// if same geometry - compound
       TopoDS_ListOfShape::Iterator aCommonIter(aFinalsCommon);
index 5b1a4ac93dfdec19a3c3c5962a77d24d19353a55..25e0f5ba404e34bb2d59262a4e59820c66c4a952 100644 (file)
@@ -36,6 +36,7 @@ class Selector_Modify: public Selector_Algo
   TDF_Label myFinal; ///< final label of the primitive or generation, where the value is
   TDF_LabelList myBases; ///< initial labels that contain shapes that produce the modification
   int myWeakIndex; ///< weak index in case modification produces several shapes
+  bool myRecomputeWeakIndex; ///< if the index is stored with old (unstable) order, recompute it
 public:
   /// Initializes the selection of this kind by list of named shapes where the modification results
   /// are presented and the selected value.
index 93e510e6cffc9782410c8d005182d633b1218f7b..2a69c252768da29922fe6fe187031449a4243653 100644 (file)
 #include <TopExp_Explorer.hxx>
 #include <TopTools_MapOfShape.hxx>
 
-#include <vector>
 #include <algorithm>
 
-static std::pair<gp_Pnt, double> ShapeToDouble (const TopoDS_Shape& S)
+static void dummy(gp_Pnt& thePoint)
+{
+  // do nothing (new approach to order shapes)
+}
+
+static void pointToDouble(gp_Pnt& thePoint)
+{
+  // old approach to order shapes
+  double dMidXYZ = thePoint.X() * 999.0 + thePoint.Y() * 99.0 + thePoint.Z() * 0.9;
+  thePoint.SetCoord(dMidXYZ, 0.0, 0.0);
+}
+
+static std::pair<gp_Pnt, double> ShapeToDouble (const TopoDS_Shape& S,
+                                                void (*convertPoint)(gp_Pnt&))
 {
   // Computing of CentreOfMass
   gp_Pnt GPoint;
@@ -61,6 +73,7 @@ static std::pair<gp_Pnt, double> ShapeToDouble (const TopoDS_Shape& S)
     Len = GPr.Mass();
   }
 
+  (*convertPoint)(GPoint);
   return std::make_pair(GPoint, Len);
 }
 
@@ -71,22 +84,24 @@ struct CompareShapes : public std::binary_function<TopoDS_Shape, TopoDS_Shape, b
 {
   typedef NCollection_DataMap<TopoDS_Shape, std::pair<gp_Pnt, double> > DataMapOfShapeDouble;
 
-  CompareShapes(DataMapOfShapeDouble* theCashMap) : myMap(theCashMap) {}
+  CompareShapes(DataMapOfShapeDouble* theCashMap, void (*convertPoint)(gp_Pnt&))
+    : myMap(theCashMap), myConvertPoint(convertPoint) {}
 
   bool operator() (const TopoDS_Shape& lhs, const TopoDS_Shape& rhs);
 
   DataMapOfShapeDouble* myMap;
+  void (*myConvertPoint)(gp_Pnt&);
 };
 
 bool CompareShapes::operator() (const TopoDS_Shape& theShape1,
   const TopoDS_Shape& theShape2)
 {
   if (!myMap->IsBound(theShape1)) {
-    myMap->Bind(theShape1, ShapeToDouble(theShape1));
+    myMap->Bind(theShape1, ShapeToDouble(theShape1, myConvertPoint));
   }
 
   if (!myMap->IsBound(theShape2)) {
-    myMap->Bind(theShape2, ShapeToDouble(theShape2));
+    myMap->Bind(theShape2, ShapeToDouble(theShape2, myConvertPoint));
   }
 
   const std::pair<gp_Pnt, double>& val1 = myMap->Find(theShape1);
@@ -139,60 +154,68 @@ bool CompareShapes::operator() (const TopoDS_Shape& theShape1,
   return !exchange;
 }
 
-Selector_NExplode::Selector_NExplode(const TopoDS_ListOfShape& theShapes)
+Selector_NExplode::Selector_NExplode(const TopoDS_ListOfShape& theShapes, const bool theOldOrder)
+  : myToBeReordered(theOldOrder)
 {
-  std::vector<TopoDS_Shape> aShapesVec;
-
   for(TopoDS_ListOfShape::Iterator anIter(theShapes); anIter.More(); anIter.Next()) {
-      aShapesVec.push_back(anIter.Value());
+    mySorted.push_back(anIter.Value());
   }
 
   CompareShapes::DataMapOfShapeDouble aCash;
-  CompareShapes shComp(&aCash);
-  std::stable_sort(aShapesVec.begin(), aShapesVec.end(), shComp);
-
-  std::vector<TopoDS_Shape>::const_iterator anIter = aShapesVec.begin();
-  for (; anIter != aShapesVec.end(); ++anIter) {
-    mySorted.Append(*anIter);
-  }
+  CompareShapes shComp(&aCash, theOldOrder ? pointToDouble : dummy);
+  std::stable_sort(mySorted.begin(), mySorted.end(), shComp);
 }
 
-Selector_NExplode::Selector_NExplode(const TopoDS_Shape& theShape, const TopAbs_ShapeEnum theType)
+Selector_NExplode::Selector_NExplode(const TopoDS_Shape& theShape, const TopAbs_ShapeEnum theType,
+                                     const bool theOldOrder)
+  : myToBeReordered(theOldOrder)
 {
-  std::vector<TopoDS_Shape> aShapesVec;
   TopTools_MapOfShape anAdded; // to avoid same shapes duplication
   for(TopExp_Explorer anExp(theShape, theType); anExp.More(); anExp.Next()) {
     if (anAdded.Add(anExp.Current()))
-     aShapesVec.push_back(anExp.Current());
+      mySorted.push_back(anExp.Current());
   }
 
   CompareShapes::DataMapOfShapeDouble aCash;
-  CompareShapes shComp(&aCash);
-  std::stable_sort(aShapesVec.begin(), aShapesVec.end(), shComp);
-
-  std::vector<TopoDS_Shape>::const_iterator anIter = aShapesVec.begin();
-  for (; anIter != aShapesVec.end(); ++anIter) {
-    mySorted.Append(*anIter);
-  }
+  CompareShapes shComp(&aCash, theOldOrder ? pointToDouble : dummy);
+  std::stable_sort(mySorted.begin(), mySorted.end(), shComp);
 }
 
 
 int Selector_NExplode::index(const TopoDS_Shape& theSubShape)
 {
-  TopoDS_ListOfShape::Iterator anIter(mySorted);
-  for(int anIndex = 1; anIter.More(); anIter.Next(), anIndex++) {
-    if (anIter.Value().IsSame(theSubShape))
+  // reorder if necessary
+  reorder();
+
+  std::vector<TopoDS_Shape>::iterator anIter = mySorted.begin();
+  for(int anIndex = 1; anIter != mySorted.end(); anIter++, anIndex++) {
+    if ((*anIter).IsSame(theSubShape))
       return anIndex;
   }
   return -1; // not found
 }
 
-TopoDS_Shape Selector_NExplode::shape(const int theIndex)
+TopoDS_Shape Selector_NExplode::shape(int& theIndex)
 {
-  TopoDS_ListOfShape::Iterator anIter(mySorted);
-  for(int anIndex = 1; anIter.More(); anIter.Next(), anIndex++) {
-    if (anIndex == theIndex)
-      return anIter.Value();
+  std::vector<TopoDS_Shape>::iterator anIter = mySorted.begin();
+  for(int anIndex = 1; anIter != mySorted.end(); anIter++, anIndex++) {
+    if (anIndex == theIndex) {
+      TopoDS_Shape aShape = *anIter;
+      if (myToBeReordered)
+        theIndex = index(aShape);
+      return aShape;
+    }
   }
   return TopoDS_Shape(); // not found
 }
+
+void Selector_NExplode::reorder()
+{
+  if (!myToBeReordered)
+    return;
+
+  myToBeReordered = false;
+  CompareShapes::DataMapOfShapeDouble aCash;
+  CompareShapes shComp(&aCash, dummy);
+  std::stable_sort(mySorted.begin(), mySorted.end(), shComp);
+}
index 849a3c2918ed27452b210c84b0c83b7c6a37f7cd..412620b8cf4629f902389e91907ee95bc9d41347 100644 (file)
@@ -23,7 +23,8 @@
 #include "Selector.h"
 
 #include <TopoDS_Shape.hxx>
-#include <TopoDS_ListOfShape.hxx>
+
+#include <vector>
 
 /// \class Selector_NExplode
 /// \ingroup DataModel
@@ -34,17 +35,26 @@ class Selector_NExplode
 {
  public:
    /// \brief Initializes the sorted list of shapes by the shapes list.
-   SELECTOR_EXPORT Selector_NExplode(const TopoDS_ListOfShape& theShapes);
+   SELECTOR_EXPORT Selector_NExplode(const TopoDS_ListOfShape& theShapes,
+                                     const bool theOldOrder = false);
    /// \brief Initializes the sorted list of shapes by the context shape and type of sub-shapes.
-   SELECTOR_EXPORT Selector_NExplode(const TopoDS_Shape& theShape, const TopAbs_ShapeEnum theType);
+   SELECTOR_EXPORT Selector_NExplode(const TopoDS_Shape& theShape,
+                                     const TopAbs_ShapeEnum theType,
+                                     const bool theOldOrder = false);
 
    /// Returns an index (started from one) of sub-shape in the sorted list. Returns 0 if not found.
    SELECTOR_EXPORT int index(const TopoDS_Shape& theSubShape);
    /// Returns a shape by an index (started from one). Returns null if not found.
-   SELECTOR_EXPORT TopoDS_Shape shape(const int theIndex);
+   /// Recompute the index if the old order was used. The value will contain the new ordered index.
+   SELECTOR_EXPORT TopoDS_Shape shape(int& theIndex);
+
+private:
+  /// Reorder list of shapes.
+  void reorder();
 
 protected:
-  TopoDS_ListOfShape mySorted; ///< keep the ordered list of shapes
+  std::vector<TopoDS_Shape> mySorted; ///< keep the ordered list of shapes
+  bool myToBeReordered; ///< the list has to be reordered
 };
 
 #endif
index 077ce7db4bc3d8d6d88443a3b38a15c5683baa92..813fa0b4e48ba80c9ea4acbfdb32d80b683361d6 100644 (file)
@@ -27,7 +27,7 @@
 #include <TNaming_Iterator.hxx>
 #include <TDataStd_Integer.hxx>
 
-Selector_WeakName::Selector_WeakName() : Selector_Algo()
+Selector_WeakName::Selector_WeakName() : Selector_Algo(), myRecomputeWeakIndex(false)
 {
 }
 
@@ -88,9 +88,11 @@ bool Selector_WeakName::restore()
 TDF_Label Selector_WeakName::restoreByName(std::string theName,
   const TopAbs_ShapeEnum theShapeType, Selector_NameGenerator* theNameGenerator)
 {
-  std::string aWeakIndex = theName.substr(pureWeakNameID().size());
+  size_t aFoundWeak = theName.find(oldPureWeakNameID());
+  std::string aWeakIndex = theName.substr(aFoundWeak + oldPureWeakNameID().size());
   std::size_t aContextPosition = aWeakIndex.find("_");
   myWeakIndex = atoi(aWeakIndex.c_str());
+  myRecomputeWeakIndex = aFoundWeak == 0;
   myShapeType = theShapeType;
   TDF_Label aContext;
   if (aContextPosition != std::string::npos) { // context is also defined
@@ -116,8 +118,9 @@ bool Selector_WeakName::solve(const TopoDS_Shape& theContext)
     }
   }
   if (!aContext.IsNull()) {
-    Selector_NExplode aNexp(aContext, myShapeType);
+    Selector_NExplode aNexp(aContext, myShapeType, myRecomputeWeakIndex);
     TopoDS_Shape aResult = aNexp.shape(myWeakIndex);
+    myRecomputeWeakIndex = false;
     if (!aResult.IsNull()) {
       Selector_Algo::store(aResult);
       return true;
index 6e2e67b25de6d8caf26b6aa281173d7ca21c342e..317dcc4af655db383a8b5a86effd61d7d7946d79 100644 (file)
@@ -31,6 +31,7 @@ class Selector_WeakName: public Selector_Algo
 {
   TopAbs_ShapeEnum myShapeType; ///< type of this shape
   int myWeakIndex; ///< weak index in case modification produces several shapes
+  bool myRecomputeWeakIndex; ///< if the index is stored with old (unstable) order, recompute it
   TDF_Label myContext; ///< context shape label
 public:
   /// Initializes the selection of this kind