From ccb9498e9a28b3db4c9b628409ae35f07e9223e6 Mon Sep 17 00:00:00 2001 From: azv Date: Fri, 1 Dec 2017 13:29:47 +0300 Subject: [PATCH] Correct processing of sketches as sub-elements of folders --- src/Model/Model_Objects.cpp | 94 +++++++++----------------- src/ModelAPI/Test/TestFolder_Sketch.py | 5 +- 2 files changed, 34 insertions(+), 65 deletions(-) diff --git a/src/Model/Model_Objects.cpp b/src/Model/Model_Objects.cpp index b5dcbbd18..0cb746e38 100644 --- a/src/Model/Model_Objects.cpp +++ b/src/Model/Model_Objects.cpp @@ -1338,6 +1338,7 @@ void Model_Objects::removeFolder(std::shared_ptr theFolder) updateHistory(ModelAPI_Feature::group()); } +// Returns one of the limiting features of the list static FeaturePtr limitingFeature(std::list& theFeatures, const bool isLast) { FeaturePtr aFeature; @@ -1351,24 +1352,11 @@ static FeaturePtr limitingFeature(std::list& theFeatures, const bool return aFeature; } -// Obtain index of last sub-feature in the composite feature. -// Parameter theIndex is an index of theComposite feature in theReferences list. -static void lastIndexOfComposite(Model_Objects* theObjectsEnt, - const FeaturePtr& theComposite, - const Handle(TDataStd_ReferenceArray)& theReferences, - int& theIndex) +// Verify the feature is sub-element in composite feature or it is not used in the history +static bool isSkippedFeature(FeaturePtr theFeature) { - CompositeFeaturePtr aComposite = - std::dynamic_pointer_cast(theComposite); - if (!aComposite) - return; - - for (; theIndex < theReferences->Upper(); ++theIndex) { - TDF_Label aNextLab = theReferences->Value(theIndex + 1); - ObjectPtr aNextObj = theObjectsEnt->object(aNextLab); - if (!aComposite->isSub(aNextObj)) - break; - } + bool isSub = ModelAPI_Tools::compositeOwner(theFeature).get() != NULL; + return isSub || (theFeature && !theFeature->isInHistory()); } std::shared_ptr Model_Objects::findFolder( @@ -1383,9 +1371,9 @@ std::shared_ptr Model_Objects::findFolder( if (!aFeaturesLab.FindAttribute(TDataStd_ReferenceArray::GetID(), aRefs)) return FolderPtr(); // no reference array (something is wrong) - // obtain first or last feature of the list according to the direction where to search a folder std::list > aFeatures = theFeatures; std::shared_ptr aLimitingFeature = limitingFeature(aFeatures, theBelow); + std::shared_ptr aData = std::static_pointer_cast(aLimitingFeature->data()); if (!aData || !aData->isValid()) @@ -1394,11 +1382,8 @@ std::shared_ptr Model_Objects::findFolder( // label of the first feature in the list for fast searching TDF_Label aFirstFeatureLabel = aData->label().Father(); - // Search applicable folder (above or below the list of features): - // [above] - find in the list of references the last folder - // before the first feature from the list; - // [below] - skip all references until last feature in the list is found, - // then check the next reference is a folder. + // find a folder above the features and + // check the given features represent a sequential list of objects following the folder FolderPtr aFoundFolder; TDF_Label aLastFeatureInFolder; int aRefIndex = aRefs->Lower(); @@ -1411,7 +1396,11 @@ std::shared_ptr Model_Objects::findFolder( if (theBelow) continue; - // skip features in the current folder + // if feature is in sub-component, skip it + FeaturePtr aCurFeature = feature(aCurLabel); + if (isSkippedFeature(aCurFeature)) + continue; + if (!aLastFeatureInFolder.IsNull()) { if (IsEqual(aCurLabel, aLastFeatureInFolder)) aLastFeatureInFolder.Nullify(); // the last feature in the folder is achived @@ -1434,18 +1423,17 @@ std::shared_ptr Model_Objects::findFolder( } } - // Skip all features in the composite until the last feature is not reached. - // Keep the index, due to aLimitingFeature may be composite, thus aRefIndex - // will be set to the last sub. But if we search a folder below the features, - // we do not want to obtain index current composite feature once again. - int anIndexCopy = aRefIndex; - lastIndexOfComposite(this, aLimitingFeature, aRefs, aRefIndex); - if (theBelow && aRefIndex < aRefs->Upper()) { + TDF_Label aLabel; + // skip following features which are sub-components or not in history + for (int anIndex = aRefIndex + 1; anIndex <= aRefs->Upper(); ++anIndex) { + aLabel = aRefs->Value(anIndex); + FeaturePtr aCurFeature = feature(aLabel); + if (!isSkippedFeature(aCurFeature)) + break; + } // check the next object is a folder - TDF_Label aLabel = aRefs->Value(aRefIndex + 1); aFoundFolder = std::dynamic_pointer_cast(folder(aLabel)); - aRefIndex = anIndexCopy; // restore index of parent composite } if (!aLastFeatureInFolder.IsNull() || // the last feature of the folder above is not found @@ -1458,29 +1446,13 @@ std::shared_ptr Model_Objects::findFolder( !aFeatures.empty() && aRefIndex >= aRefs->Lower() && aRefIndex <= aRefs->Upper(); aRefIndex += aStep) { TDF_Label aCurLabel = aRefs->Value(aRefIndex); - TDF_Label aFeatureLabel; + // if feature is in sub-component, skip it + FeaturePtr aCurFeature = feature(aCurLabel); + if (isSkippedFeature(aCurFeature)) + continue; aLimitingFeature = limitingFeature(aFeatures, theBelow); - aData = std::static_pointer_cast(aLimitingFeature->data()); - if (aData && aData->isValid()) - aFeatureLabel = aData->label().Father(); - - if (theBelow) { - // find index of parent composite feature - FeaturePtr aComposite = ModelAPI_Tools::compositeOwner(feature(aCurLabel)); - if (aComposite) { - aData = std::static_pointer_cast(aComposite->data()); - if (aData && aData->isValid()) - aCurLabel = aData->label().Father(); - while (aRefs->Value(aRefIndex) != aCurLabel) - --aRefIndex; - } - } else { - // skip all features in the composite until the last feature is not reached - lastIndexOfComposite(this, aLimitingFeature, aRefs, aRefIndex); - } - - if (!IsEqual(aCurLabel, aFeatureLabel)) + if (!aCurFeature->data()->isEqual(aLimitingFeature->data())) return FolderPtr(); // not a sequential list } @@ -1495,17 +1467,11 @@ bool Model_Objects::moveToFolder( return false; // labels for the folder and last feature in the list - // (if the last feature is composite, obtain label of the last sub-feature) TDF_Label aFolderLabel, aLastFeatureLabel; std::shared_ptr aData = std::static_pointer_cast(theFolder->data()); if (aData && aData->isValid()) aFolderLabel = aData->label().Father(); - FeaturePtr aLastFeature = theFeatures.back(); - CompositeFeaturePtr aComposite = - std::dynamic_pointer_cast(aLastFeature); - if (aComposite) - aLastFeature = aComposite->subFeature(aComposite->numberOfSubs() - 1); aData = std::static_pointer_cast(theFeatures.back()->data()); if (aData && aData->isValid()) aLastFeatureLabel = aData->label().Father(); @@ -1632,7 +1598,8 @@ bool Model_Objects::removeFromFolder( FeaturePtr aFeatureToFind; if (isExtractBeforeFolder) { aFeatureToFind = theFeatures.back(); - // if the last feature is composite, obtain its last sub-feature + // if the last feature is composite, obtain its last sub-feature for correct positioning of + // the folder in the reference array when theFeatures will be extracted before folder CompositeFeaturePtr aComposite = std::dynamic_pointer_cast(aFeatureToFind); if (aComposite) @@ -1699,10 +1666,13 @@ FolderPtr Model_Objects::findContainingFolder(const FeaturePtr& theFeature, int& TDF_Label aLastFeatureLabel; for (int aRefIndex = aRefs->Lower(); aRefIndex <= aRefs->Upper(); ++aRefIndex) { + TDF_Label aCurLabel = aRefs->Value(aRefIndex); + if (isSkippedFeature(feature(aCurLabel))) + continue; + if (aFoundFolder) ++theIndexInFolder; - TDF_Label aCurLabel = aRefs->Value(aRefIndex); if (aCurLabel == aLabelToFind) // the feature is reached return aFoundFolder; diff --git a/src/ModelAPI/Test/TestFolder_Sketch.py b/src/ModelAPI/Test/TestFolder_Sketch.py index fb7cbf1c6..bf6768a1f 100644 --- a/src/ModelAPI/Test/TestFolder_Sketch.py +++ b/src/ModelAPI/Test/TestFolder_Sketch.py @@ -37,12 +37,12 @@ model.do() Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY")) SketchCircle_1 = Sketch_1.addCircle(50, 50, 25) model.do() -Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchCircle_1_2f")], model.selection(), 50, 0) +Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchCircle_1_2f")], model.selection(), 50, 0) Sketch_2 = model.addSketch(Part_1_doc, model.standardPlane("XOY")) SketchCircle_2 = Sketch_2.addCircle(100, -100, 50) model.do() -Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_2")], model.selection(), 10, 0) +Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_3")], model.selection(), 10, 0) ExtrusionCut_1 = model.addExtrusionCut(Part_1_doc, [], model.selection(), 0, 10, [model.selection("SOLID", "Extrusion_2_1")]) Sketch_3 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_2_1/To_Face_1")) SketchProjection_1 = Sketch_3.addProjection(model.selection("VERTEX", "Extrusion_2_1/Generated_Face_1&Extrusion_2_1/To_Face_1__cc"), False) @@ -57,7 +57,6 @@ model.end() aSession = ModelAPI_Session.get() aPartDoc = aSession.activeDocument() - #========================================================================= # Test 1. Sketch and extrusion could be added to the folder above #========================================================================= -- 2.39.2