From e3fa38d82c331df1c34de068d74dacc76a630687 Mon Sep 17 00:00:00 2001 From: azv Date: Mon, 27 Nov 2017 15:47:05 +0300 Subject: [PATCH] Implement a method for searching a folder containing given feature and getting an index of the feature in the folder. --- src/Model/Model_Document.cpp | 7 ++++ src/Model/Model_Document.h | 8 ++++ src/Model/Model_Objects.cpp | 53 ++++++++++++++++++++++++++ src/Model/Model_Objects.h | 8 ++++ src/ModelAPI/ModelAPI.i | 2 + src/ModelAPI/ModelAPI_Document.h | 8 ++++ src/ModelAPI/Test/TestFolder_Update.py | 20 ++++++++++ 7 files changed, 106 insertions(+) diff --git a/src/Model/Model_Document.cpp b/src/Model/Model_Document.cpp index 2be9514ca..9f4b130cc 100755 --- a/src/Model/Model_Document.cpp +++ b/src/Model/Model_Document.cpp @@ -1282,6 +1282,13 @@ std::shared_ptr Model_Document::findFolderBelow( return myObjs->findFolder(theFeatures, true); } +std::shared_ptr Model_Document::findContainingFolder( + const std::shared_ptr& theFeature, + int& theIndexInFolder) +{ + return myObjs->findContainingFolder(theFeature, theIndexInFolder); +} + bool Model_Document::moveToFolder( const std::list >& theFeatures, const std::shared_ptr& theFolder) diff --git a/src/Model/Model_Document.h b/src/Model/Model_Document.h index d4c178103..68f2fcce9 100644 --- a/src/Model/Model_Document.h +++ b/src/Model/Model_Document.h @@ -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 findFolderBelow( const std::list >& 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 findContainingFolder( + const std::shared_ptr& 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 diff --git a/src/Model/Model_Objects.cpp b/src/Model/Model_Objects.cpp index 92b57970c..dafcd5c28 100644 --- a/src/Model/Model_Objects.cpp +++ b/src/Model/Model_Objects.cpp @@ -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 aData = + std::static_pointer_cast(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(folder(aCurLabel)); + if (aFoundFolder) { + theIndexInFolder = -1; + + AttributeReferencePtr aLastRef = + aFoundFolder->reference(ModelAPI_Folder::LAST_FEATURE_ID()); + if (aLastRef->value()) { + aData = std::static_pointer_cast(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 Model_Objects::feature( const std::shared_ptr& theResult) diff --git a/src/Model/Model_Objects.h b/src/Model/Model_Objects.h index 19572e143..856d3c90b 100644 --- a/src/Model/Model_Objects.h +++ b/src/Model/Model_Objects.h @@ -162,6 +162,14 @@ class Model_Objects std::shared_ptr findFolder( const std::list >& 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 findContainingFolder( + const std::shared_ptr& 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 diff --git a/src/ModelAPI/ModelAPI.i b/src/ModelAPI/ModelAPI.i index 6e03cd6ed..3d269b3ed 100644 --- a/src/ModelAPI/ModelAPI.i +++ b/src/ModelAPI/ModelAPI.i @@ -116,6 +116,8 @@ } } +%apply int& OUTPUT {int&}; + // all supported interfaces %include "ModelAPI_Entity.h" %include "ModelAPI_Document.h" diff --git a/src/ModelAPI/ModelAPI_Document.h b/src/ModelAPI/ModelAPI_Document.h index dc4160da4..e234aefe5 100644 --- a/src/ModelAPI/ModelAPI_Document.h +++ b/src/ModelAPI/ModelAPI_Document.h @@ -198,6 +198,14 @@ public: //! \return Empty pointer if there is no applicable folder virtual std::shared_ptr findFolderBelow( const std::list >& 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 findContainingFolder( + const std::shared_ptr& 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 diff --git a/src/ModelAPI/Test/TestFolder_Update.py b/src/ModelAPI/Test/TestFolder_Update.py index a118cbacf..c16eb03c3 100644 --- a/src/ModelAPI/Test/TestFolder_Update.py +++ b/src/ModelAPI/Test/TestFolder_Update.py @@ -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.) -- 2.39.2