]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Correct names generation for tests.
authormpv <mpv@opencascade.com>
Thu, 16 Nov 2017 12:22:05 +0000 (15:22 +0300)
committermpv <mpv@opencascade.com>
Thu, 16 Nov 2017 12:22:05 +0000 (15:22 +0300)
src/Model/Model_Document.cpp
src/Model/Model_Document.h
src/Model/Model_Objects.cpp
src/Model/Model_SelectionNaming.cpp
src/ModelAPI/Test/Test1757.py
test.API/SHAPER/Transformations/TestTranslation_3.py

index 2272a8f33c4efa51896d4058f30e66a88e507d99..bb82a340e7190215deda3d9b8459ad96cb9236de 100755 (executable)
@@ -1271,10 +1271,22 @@ Standard_Boolean IsEqual(const TDF_Label& theLab1, const TDF_Label& theLab2)
   return TDF_LabelMapHasher::IsEqual(theLab1, theLab2);
 }
 
+// searches in this document feature that contains this label
+FeaturePtr Model_Document::featureByLab(const TDF_Label& theLab) {
+  TDF_Label aCurrentLab = theLab;
+  while(aCurrentLab.Depth() > 3)
+    aCurrentLab = aCurrentLab.Father();
+  return myObjs->feature(aCurrentLab);
+}
+
 void Model_Document::addNamingName(const TDF_Label theLabel, std::string theName)
 {
   std::map<std::string, std::list<TDF_Label> >::iterator aFind = myNamingNames.find(theName);
+
   if (aFind != myNamingNames.end()) { // to avoid duplicate-labels
+    // to keep correct order inspite of history line management
+    std::list<TDF_Label>::iterator anAddAfterThis = aFind->second.end();
+    FeaturePtr anAddedFeature = featureByLab(theLabel);
     std::list<TDF_Label>::iterator aLabIter = aFind->second.begin();
     while(aLabIter != aFind->second.end()) {
       if (theLabel.IsEqual(*aLabIter)) {
@@ -1282,9 +1294,21 @@ void Model_Document::addNamingName(const TDF_Label theLabel, std::string theName
         aLabIter++;
         aFind->second.erase(aTmpIter);
       } else {
+        FeaturePtr aCurFeature = featureByLab(*aLabIter);
+        if (aCurFeature.get() && anAddedFeature.get() &&
+            myObjs->isLater(anAddedFeature, aCurFeature))
+          anAddAfterThis = aLabIter;
+
         aLabIter++;
       }
     }
+    if (anAddAfterThis != aFind->second.end()) {
+      anAddAfterThis++;
+      if (anAddAfterThis != aFind->second.end()) {
+        myNamingNames[theName].insert(anAddAfterThis, theLabel); // inserts before anAddAfterThis
+        return;
+      }
+    }
   }
   myNamingNames[theName].push_back(theLabel);
 }
@@ -1366,6 +1390,30 @@ TDF_Label Model_Document::findNamingName(std::string theName, ResultPtr theConte
   return TDF_Label(); // not found
 }
 
+bool Model_Document::isLaterByDep(FeaturePtr theThis, FeaturePtr theOther) {
+  // check dependencies first: if theOther depends on theThis, theThis is not later
+  std::list<std::pair<std::string, std::list<std::shared_ptr<ModelAPI_Object> > > > aRefs;
+  theOther->data()->referencesToObjects(aRefs);
+  std::list<std::pair<std::string, std::list<std::shared_ptr<ModelAPI_Object> > > >::iterator
+    aRefIt = aRefs.begin();
+  for(; aRefIt != aRefs.end(); aRefIt++) {
+    std::list<ObjectPtr>::iterator aRefObjIt = aRefIt->second.begin();
+    for(; aRefObjIt != aRefIt->second.end(); aRefObjIt++) {
+      ObjectPtr aRefObj = *aRefObjIt;
+      if (aRefObj.get()) {
+        FeaturePtr aRefFeat = std::dynamic_pointer_cast<ModelAPI_Feature>(aRefObj);
+        if (!aRefFeat.get()) { // take feature of the result
+          aRefFeat = feature(std::dynamic_pointer_cast<ModelAPI_Result>(aRefObj));
+        }
+        if (aRefFeat.get() && aRefFeat == theThis) {
+          return false; // other references to this, so this later than other
+        }
+      }
+    }
+  }
+  return myObjs->isLater(theThis, theOther);
+}
+
 int Model_Document::numberOfNameInHistory(
   const ObjectPtr& theNameObject, const TDF_Label& theStartFrom)
 {
@@ -1388,35 +1436,31 @@ int Model_Document::numberOfNameInHistory(
   // iterate all labels with this name to find the nearest just before or equal relative
   std::list<TDF_Label>::reverse_iterator aLabIter = aFind->second.rbegin();
   for(; aLabIter != aFind->second.rend(); aLabIter++) {
-    TDF_Label aCurrentLab = *aLabIter;
-    while(aCurrentLab.Depth() > 3)
-      aCurrentLab = aCurrentLab.Father();
-    FeaturePtr aLabFeat = myObjs->feature(aCurrentLab);
+    FeaturePtr aLabFeat = featureByLab(*aLabIter);
     if (!aLabFeat.get())
       continue;
-    if (aLabFeat == aStart || myObjs->isLater(aStart, aLabFeat))
+    if (isLaterByDep(aStart, aLabFeat)) // skip also start: its result don't used
       break;
   }
   int aResIndex = 1;
   for(; aLabIter != aFind->second.rend(); aLabIter++) {
-    TDF_Label aCurrentLab = *aLabIter;
-    while(aCurrentLab.Depth() > 3)
-      aCurrentLab = aCurrentLab.Father();
-    FeaturePtr aLabFeat = myObjs->feature(aCurrentLab);
+    FeaturePtr aLabFeat = featureByLab(*aLabIter);
     if (!aLabFeat.get())
       continue;
-    if (aLabFeat == aNameFeature || myObjs->isLater(aNameFeature, aLabFeat))
+    if (aLabFeat == aNameFeature || isLaterByDep(aNameFeature, aLabFeat))
       return aResIndex;
     aResIndex++;
   }
   return aResIndex; // strange
 }
 
-ResultPtr Model_Document::findByName(std::string& theName, std::string& theSubShapeName)
+ResultPtr Model_Document::findByName(
+  std::string& theName, std::string& theSubShapeName, bool& theUniqueContext)
 {
   int aNumInHistory = 0;
   std::string aName = theName;
   ResultPtr aRes = myObjs->findByName(aName);
+  theUniqueContext = !(aRes.get() && myNamingNames.find(aName) != myNamingNames.end());
   while(!aRes.get() && aName[0] == '_') { // this may be thecontext with the history index
     aNumInHistory++;
     aName = aName.substr(1);
index 93f50e3590590914c8de3c1fcb89306ae84eef23..4b33be6af7044e11e3edd715c35eb1dfc82f692f 100644 (file)
@@ -215,7 +215,7 @@ class Model_Document : public ModelAPI_Document
   int numberOfNameInHistory(const ObjectPtr& theNameObject, const TDF_Label& theStartFrom);
   //! Returns the result by name of the result (names of results must be unique, used for naming
   //! selection by name.
-  ResultPtr findByName(std::string& theName, std::string& theSubShapeName);
+  ResultPtr findByName(std::string& theName, std::string& theSubShapeName, bool& theUniqueContext);
 
   ///! Returns all features of the document including the hidden features which are not in
   ///! history. Not very fast method, for calling once, not in big cycles.
@@ -313,6 +313,12 @@ class Model_Document : public ModelAPI_Document
   /// Label that constains structures for selection of constructions of another document
   TDF_Label extConstructionsLabel() const;
 
+  /// searches in this document feature that contains this label
+  FeaturePtr featureByLab(const TDF_Label& theLab);
+
+  /// returns true if theThis is later in the features trre and dependencies than theOther
+  bool isLaterByDep(FeaturePtr theThis, FeaturePtr theOther);
+
   friend class Model_Application;
   friend class Model_Session;
   friend class Model_Update;
index e1636118df3e9d6362dd4cb5ec205a567287bcc4..85460450ce703b410da807ee6836e5cd974a2f19 100644 (file)
@@ -1222,6 +1222,8 @@ void Model_Objects::updateResults(FeaturePtr theFeature, std::set<FeaturePtr>& t
 
 ResultPtr Model_Objects::findByName(const std::string theName)
 {
+  ResultPtr aResult;
+  FeaturePtr aResFeature; // keep feature to return the latest one
   NCollection_DataMap<TDF_Label, FeaturePtr>::Iterator anObjIter(myFeatures);
   for(; anObjIter.More(); anObjIter.Next()) {
     FeaturePtr& aFeature = anObjIter.ChangeValue();
@@ -1233,13 +1235,16 @@ ResultPtr Model_Objects::findByName(const std::string theName)
     for (; aRIter != allResults.cend(); aRIter++) {
       ResultPtr aRes = *aRIter;
       if (aRes.get() && aRes->data() && aRes->data()->isValid() && !aRes->isDisabled() &&
-          aRes->data()->name() == theName) {
-        return aRes;
+          aRes->data()->name() == theName)
+      {
+        if (!aResult.get() || isLater(aFeature, aResFeature)) { // select the latest
+          aResult = aRes;
+          aResFeature = aFeature;
+        }
       }
     }
   }
-  // not found
-  return ResultPtr();
+  return aResult;
 }
 
 FeaturePtr Model_Objects::nextFeature(FeaturePtr theCurrent, const bool theReverse)
index ad202ae1b4839eea29381cad931e215ba2b7a793..6de12da8d0ad49553c9819a2ae402c9ae9bc86fa 100644 (file)
@@ -484,17 +484,20 @@ const TopoDS_Shape getShapeFromNS(
 
 const TopoDS_Shape findFaceByName(
   const std::string& theSubShapeName, std::shared_ptr<Model_Document> theDoc,
-  const ResultPtr theDetectedContext)
+  const ResultPtr theDetectedContext, bool theContextIsUnique)
 {
   TopoDS_Shape aFace;
   std::string aSubString = theSubShapeName;
 
-  TDF_Label aLabel = theDoc->findNamingName(aSubString, theDetectedContext);
+  static const ResultPtr anEmpty;
+  TDF_Label aLabel = theDoc->findNamingName(aSubString,
+    theContextIsUnique ? theDetectedContext : anEmpty);
   if (aLabel.IsNull()) { // try to remove additional artificial suffix
     std::string::size_type n = aSubString.rfind('_');
     if (n != std::string::npos) {
       aSubString = aSubString.substr(0, n);
-       aLabel = theDoc->findNamingName(aSubString, theDetectedContext);
+      aLabel = theDoc->findNamingName(aSubString,
+        theContextIsUnique ? theDetectedContext : anEmpty);
     }
   }
   if(aLabel.IsNull()) return aFace;
@@ -733,7 +736,8 @@ bool Model_SelectionNaming::selectSubShape(const std::string& theType,
 
   std::string aContName = getContextName(aSubShapeName);
   if(aContName.empty()) return false;
-  ResultPtr aCont = aDoc->findByName(aContName, aSubShapeName);
+  bool anUniqueContext = false;
+  ResultPtr aCont = aDoc->findByName(aContName, aSubShapeName, anUniqueContext);
    // possible this is body where postfix is added to distinguish several shapes on the same label
   int aSubShapeId = -1; // -1 means sub shape not found
   // for result body the name wihtout "_" has higher priority than with it: it is always added
@@ -742,7 +746,7 @@ bool Model_SelectionNaming::selectSubShape(const std::string& theType,
     size_t aPostIndex = aContName.rfind('_');
     if (aPostIndex != std::string::npos) {
       std::string anEmpty, aSubContName = aContName.substr(0, aPostIndex);
-      ResultPtr aSubCont = aDoc->findByName(aSubContName, anEmpty);
+      ResultPtr aSubCont = aDoc->findByName(aSubContName, anEmpty, anUniqueContext);
       if (aSubCont.get()) {
         try {
           std::string aNum = aContName.substr(aPostIndex + 1);
@@ -759,18 +763,20 @@ bool Model_SelectionNaming::selectSubShape(const std::string& theType,
   }
 
 
+  static const ResultPtr anEmpty;
   TopoDS_Shape aSelection;
   switch (aType)
   {
   case TopAbs_FACE:
   case TopAbs_WIRE:
     {
-      aSelection = findFaceByName(aSubShapeName, aDoc, aCont);
+      aSelection = findFaceByName(aSubShapeName, aDoc, aCont, anUniqueContext);
     }
     break;
   case TopAbs_EDGE:
     {
-      const TDF_Label& aLabel = aDoc->findNamingName(aSubShapeName, aCont);
+      const TDF_Label& aLabel =
+        aDoc->findNamingName(aSubShapeName, anUniqueContext ? aCont : anEmpty);
       if(!aLabel.IsNull()) {
         Handle(TNaming_NamedShape) aNS;
         if(aLabel.FindAttribute(TNaming_NamedShape::GetID(), aNS)) {
@@ -781,7 +787,8 @@ bool Model_SelectionNaming::selectSubShape(const std::string& theType,
     break;
   case TopAbs_VERTEX:
     {
-      const TDF_Label& aLabel = aDoc->findNamingName(aSubShapeName, aCont);
+      const TDF_Label& aLabel =
+        aDoc->findNamingName(aSubShapeName, anUniqueContext ? aCont : anEmpty);
       if(!aLabel.IsNull()) {
         Handle(TNaming_NamedShape) aNS;
         if(aLabel.FindAttribute(TNaming_NamedShape::GetID(), aNS)) {
@@ -834,10 +841,10 @@ bool Model_SelectionNaming::selectSubShape(const std::string& theType,
         if (it != aListofNames.begin()) { // there may be other context for different sub-faces
           std::string aContName = getContextName(*it);
           if(!aContName.empty()) {
-            aFaceContext = aDoc->findByName(aContName, *it);
+            aFaceContext = aDoc->findByName(aContName, *it, anUniqueContext);
           }
         }
-        const TopoDS_Shape aFace = findFaceByName(*it, aDoc, aFaceContext);
+        const TopoDS_Shape aFace = findFaceByName(*it, aDoc, aFaceContext, anUniqueContext);
         if(!aFace.IsNull())
           aList.Append(aFace);
       }
@@ -850,7 +857,7 @@ bool Model_SelectionNaming::selectSubShape(const std::string& theType,
     size_t aConstrNamePos = aSubShapeName.find("/");
     bool isFullName = aConstrNamePos == std::string::npos;
     std::string anEmpty, aContrName = aContName;
-    ResultPtr aConstr = aDoc->findByName(aContrName, anEmpty);
+    ResultPtr aConstr = aDoc->findByName(aContrName, anEmpty, anUniqueContext);
     if (aConstr.get() && aConstr->groupName() == ModelAPI_ResultConstruction::group()) {
       theCont = aConstr;
       if (isFullName) {
index e76525a1efcef5fccc7f271e0a3097aaa7ab1526..8c300a57886effcf4f02b764f1dc0f22db8030dd 100644 (file)
@@ -79,7 +79,7 @@ model.do()
 #=========================================================================
 # Make a cylindrical hole using one of the produced faces
 #=========================================================================
-ExtrusionCut_2 = model.addExtrusionCut(Part_1_doc, [], model.selection(), model.selection(), 0, model.selection("FACE", "__Extrusion_1_1/Generated_Face_2"), 0, [model.selection("SOLID", "Extrusion_1_1")])
+ExtrusionCut_2 = model.addExtrusionCut(Part_1_doc, [], model.selection(), model.selection(), 0, model.selection("FACE", "_Extrusion_1_1/Generated_Face_2"), 0, [model.selection("SOLID", "Extrusion_1_1")])
 Sketch_3 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Modfied_4"))
 SketchCircle_1 = Sketch_3.addCircle(143.412751420315, -228.52745656314, 32.158435160764)
 ExtrusionCut_2.setNestedSketch(Sketch_3)
@@ -125,6 +125,6 @@ import ModelAPI
 
 assert(ModelAPI.ModelAPI_Session.get().validators().validate(Sketch_4.feature()))
 assert(ModelAPI.ModelAPI_Session.get().validators().validate(ExtrusionCut_2.feature()))
-assert(Sketch_3.feature().selection("External").namingName() == "ExtrusionCut_3_1/Modfied_6")
+assert(Sketch_3.feature().selection("External").namingName() == "Extrusion_1_1/Modfied_6")
 
 assert(model.checkPythonDump())
index 8d7af9855c22c26dfc710a9442c928ae892f1ece..dadc9d953e52076dc434e5f7b46891a5b3676173 100644 (file)
@@ -162,14 +162,23 @@ Face_13 = model.addFace(Part_1_doc, [model.selection("WIRE", "Sketch_7/Wire-Sket
 
 # Shells
 Shell_1 = model.addShell(Part_1_doc, [model.selection("FACE", "Face_10_1"), model.selection("FACE", "Face_11_1")])
+Shell_1.result().setName("Shell_1_1")
 Shell_2 = model.addShell(Part_1_doc, [model.selection("FACE", "Face_10_1"), model.selection("FACE", "Face_11_1")])
+Shell_2.result().setName("Shell_2_1")
 Shell_3 = model.addShell(Part_1_doc, [model.selection("FACE", "Face_10_1"), model.selection("FACE", "Face_11_1")])
+Shell_3.result().setName("Shell_3_1")
 Shell_4 = model.addShell(Part_1_doc, [model.selection("FACE", "Face_10_1"), model.selection("FACE", "Face_11_1")])
+Shell_4.result().setName("Shell_4_1")
 Shell_5 = model.addShell(Part_1_doc, [model.selection("FACE", "Face_10_1"), model.selection("FACE", "Face_11_1")])
+Shell_5.result().setName("Shell_5_1")
 Shell_6 = model.addShell(Part_1_doc, [model.selection("FACE", "Face_12_1"), model.selection("FACE", "Face_13_1")])
+Shell_6.result().setName("Shell_6_1")
 Shell_7 = model.addShell(Part_1_doc, [model.selection("FACE", "Face_12_1"), model.selection("FACE", "Face_13_1")])
+Shell_7.result().setName("Shell_7_1")
 Shell_8 = model.addShell(Part_1_doc, [model.selection("FACE", "Face_10_1"), model.selection("FACE", "Face_11_1")])
+Shell_8.result().setName("Shell_8_1")
 Shell_9 = model.addShell(Part_1_doc, [model.selection("FACE", "Face_10_1"), model.selection("FACE", "Face_11_1")])
+Shell_9.result().setName("Shell_9_1")
 
 # Parameters
 model.addParameter(Part_1_doc, "d", "15")