]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Implement a method for searching a folder containing given feature and getting an...
authorazv <azv@opencascade.com>
Mon, 27 Nov 2017 12:47:05 +0000 (15:47 +0300)
committerazv <azv@opencascade.com>
Mon, 27 Nov 2017 12:47:05 +0000 (15:47 +0300)
src/Model/Model_Document.cpp
src/Model/Model_Document.h
src/Model/Model_Objects.cpp
src/Model/Model_Objects.h
src/ModelAPI/ModelAPI.i
src/ModelAPI/ModelAPI_Document.h
src/ModelAPI/Test/TestFolder_Update.py

index 2be9514ca24746c6218041a740d7df0bca72d864..9f4b130cc5d5cd43411fa020bea68e8768c9e63f 100755 (executable)
@@ -1282,6 +1282,13 @@ std::shared_ptr<ModelAPI_Folder> Model_Document::findFolderBelow(
   return myObjs->findFolder(theFeatures, true);
 }
 
+std::shared_ptr<ModelAPI_Folder> Model_Document::findContainingFolder(
+      const std::shared_ptr<ModelAPI_Feature>& theFeature,
+      int& theIndexInFolder)
+{
+  return myObjs->findContainingFolder(theFeature, theIndexInFolder);
+}
+
 bool Model_Document::moveToFolder(
       const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures,
       const std::shared_ptr<ModelAPI_Folder>& theFolder)
index d4c178103ded8fd2da022de13657fda43ede292a..68f2fcce9d7958d2da46a53e29dc5e47bc217a4a 100644 (file)
@@ -223,6 +223,14 @@ class Model_Document : public ModelAPI_Document
   //! \return Empty pointer if there is no applicable folder
   MODEL_EXPORT virtual std::shared_ptr<ModelAPI_Folder> findFolderBelow(
       const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures);
+  //! Search a folder containing the given feature.
+  //! Addtionally calculates a zero-based index of the feature in this folder.
+  //! \param theFeature feature to search
+  //! \param theIndexInFolder zero-based index in the folder or -1 if the feature is top-level.
+  //! \return the folder containing the feature or empty pointer if the feature is top-level.
+  MODEL_EXPORT virtual std::shared_ptr<ModelAPI_Folder> findContainingFolder(
+      const std::shared_ptr<ModelAPI_Feature>& theFeature,
+      int& theIndexInFolder);
   //! Add a list of features to the folder. The correctness of the adding is not performed
   //! (such checks have been done in corresponding find.. method).
   //! \return \c true if the movement is successfull
index 92b57970c79b32ad74c0852767437b952861d5d7..dafcd5c287c9d081109140b4b597a242a894db0e 100644 (file)
@@ -1580,6 +1580,59 @@ bool Model_Objects::removeFromFolder(
   return true;
 }
 
+FolderPtr Model_Objects::findContainingFolder(const FeaturePtr& theFeature, int& theIndexInFolder)
+{
+  // search the label in the list of references
+  TDF_Label aFeaturesLab = featuresLabel();
+  Handle(TDataStd_ReferenceArray) aRefs;
+  if (!aFeaturesLab.FindAttribute(TDataStd_ReferenceArray::GetID(), aRefs))
+    return FolderPtr(); // no reference array (something is wrong)
+
+  std::shared_ptr<Model_Data> aData =
+      std::static_pointer_cast<Model_Data>(theFeature->data());
+  if (!aData || !aData->isValid())
+    return FolderPtr();
+  TDF_Label aLabelToFind = aData->label().Father();
+
+  theIndexInFolder = -1;
+  FolderPtr aFoundFolder;
+  TDF_Label aLastFeatureLabel;
+
+  for (int aRefIndex = aRefs->Lower(); aRefIndex <= aRefs->Upper(); ++aRefIndex) {
+    if (aFoundFolder)
+      ++theIndexInFolder;
+
+    TDF_Label aCurLabel = aRefs->Value(aRefIndex);
+    if (aCurLabel == aLabelToFind) // the feature is reached
+      return aFoundFolder;
+
+    if (!aFoundFolder) {
+      // if the current label refers to a folder, feel all necessary data
+      aFoundFolder = std::dynamic_pointer_cast<ModelAPI_Folder>(folder(aCurLabel));
+      if (aFoundFolder) {
+        theIndexInFolder = -1;
+
+        AttributeReferencePtr aLastRef =
+            aFoundFolder->reference(ModelAPI_Folder::LAST_FEATURE_ID());
+        if (aLastRef->value()) {
+          aData = std::static_pointer_cast<Model_Data>(aLastRef->value()->data());
+          if (aData && aData->isValid())
+            aLastFeatureLabel = aData->label().Father();
+        } else // folder is empty
+          aFoundFolder = FolderPtr();
+      }
+    } else if (aLastFeatureLabel == aCurLabel) {
+      // folder is finished, clear all stored data
+      theIndexInFolder = -1;
+      aFoundFolder = FolderPtr();
+    }
+  }
+
+  // folder is not found
+  theIndexInFolder = -1;
+  return FolderPtr();
+}
+
 
 std::shared_ptr<ModelAPI_Feature> Model_Objects::feature(
     const std::shared_ptr<ModelAPI_Result>& theResult)
index 19572e143001cce978f159a0c629c30f5d6bfb88..856d3c90b12f87cb96a40e91ada6c4dec8ac0327 100644 (file)
@@ -162,6 +162,14 @@ class Model_Objects
   std::shared_ptr<ModelAPI_Folder> findFolder(
       const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures,
       const bool theBelow);
+  //! Search a folder containing the given feature.
+  //! Addtionally calculates a zero-based index of the feature in this folder.
+  //! \param theFeature feature to search
+  //! \param theIndexInFolder zero-based index in the folder or -1 if the feature is top-level.
+  //! \return the folder containing the feature or empty pointer if the feature is top-level.
+  std::shared_ptr<ModelAPI_Folder> findContainingFolder(
+      const std::shared_ptr<ModelAPI_Feature>& theFeature,
+      int& theIndexInFolder);
   //! Add a list of features to the folder. The correctness of the adding is not performed
   //! (such checks have been done in corresponding find.. method).
   //! \return \c true if the movement is successfull
index 6e03cd6ed8ca25f2b87e91bf6f2b20661073d52e..3d269b3ed5a0f8564e55a5cbd8147804eb220f0a 100644 (file)
   }
 }
 
+%apply int& OUTPUT {int&};
+
 // all supported interfaces
 %include "ModelAPI_Entity.h"
 %include "ModelAPI_Document.h"
index dc4160da4041ccbfde7cce899eb446d006c8485f..e234aefe5a45721b42e061dde2a01a58b0e4702b 100644 (file)
@@ -198,6 +198,14 @@ public:
   //! \return Empty pointer if there is no applicable folder
   virtual std::shared_ptr<ModelAPI_Folder> findFolderBelow(
       const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures) = 0;
+  //! Search a folder containing the given feature.
+  //! Addtionally calculates a zero-based index of the feature in this folder.
+  //! \param theFeature feature to search
+  //! \param theIndexInFolder zero-based index in the folder or -1 if the feature is top-level.
+  //! \return the folder containing the feature or empty pointer if the feature is top-level.
+  virtual std::shared_ptr<ModelAPI_Folder> findContainingFolder(
+      const std::shared_ptr<ModelAPI_Feature>& theFeature,
+      int& theIndexInFolder) = 0;
   //! Add a list of features to the folder. The correctness of the adding is not performed
   //! (such checks have been done in corresponding find.. method).
   //! \return \c true if the movement is successfull
index a118cbacfe4fc87d3df5332ffd1b4f094899589c..c16eb03c380c5662d2522f85ca694832978c91ca 100644 (file)
@@ -80,6 +80,11 @@ assert(aPartDoc.size("Features") == NB_FEATURES_FULL), "Wrong number of features
 # number of features outside the folder
 assert(aPartDoc.size("Features", True) == NB_FEATURES_OUT), "Wrong number of features outside a folder: {}, expected: {}".format(aPartDoc.size("Features", True), NB_FEATURES_OUT)
 
+# check the index of the point in the folder
+aFound = aPartDoc.findContainingFolder(aPoint1)
+assert(aFound[0].data().isEqual(aFolder1.data()))
+assert(aFound[1] == 0)
+
 #=========================================================================
 # Test 2. Add a point into a folder below
 #=========================================================================
@@ -120,6 +125,13 @@ NB_FEATURES_OUT -= 1
 assert(aPartDoc.size("Features") == NB_FEATURES_FULL), "Wrong number of features: {}, expected: {}".format(aPartDoc.size("Features"), NB_FEATURES_FULL)
 assert(aPartDoc.size("Features", True) == NB_FEATURES_OUT), "Wrong number of features outside a folder: {}, expected: {}".format(aPartDoc.size("Features", True), NB_FEATURES_OUT)
 
+# check the index of the point in the folder
+aFound = aPartDoc.findContainingFolder(aPoint2)
+assert(aFound[0].data().isEqual(aFolder2.data()))
+assert(aFound[1] == 0)
+aFound = aPartDoc.findContainingFolder(aPoint3)
+assert(aFound == -1)
+
 #=========================================================================
 # Test 3. Add several points into a folder
 #=========================================================================
@@ -181,6 +193,14 @@ assert(aPartDoc.index(aFolder3, True) == 2), "Wrong index of the folder: {}".for
 assert(aPartDoc.index(aPoint3, True) == -1), "Wrong index of the point: {}".format(aPartDoc.index(aPoint3, True))
 assert(aPartDoc.index(aPoint4, True) == -1), "Wrong index of the point: {}".format(aPartDoc.index(aPoint4, True))
 
+# check the index of the point in the folder
+aFound = aPartDoc.findContainingFolder(aPoint3)
+assert(aFound[0].data().isEqual(aFolder3.data()))
+assert(aFound[1] == 0)
+aFound = aPartDoc.findContainingFolder(aPoint4)
+assert(aFound[0].data().isEqual(aFolder3.data()))
+assert(aFound[1] == 1)
+
 
 # add more points to the folder to move them out
 aPoint5 = newPoint(aPartDoc, 0., 0., 10.)