]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Correct processing of sketches as sub-elements of folders
authorazv <azv@opencascade.com>
Fri, 1 Dec 2017 10:29:47 +0000 (13:29 +0300)
committerazv <azv@opencascade.com>
Fri, 1 Dec 2017 10:29:47 +0000 (13:29 +0300)
src/Model/Model_Objects.cpp
src/ModelAPI/Test/TestFolder_Sketch.py

index b5dcbbd18ad1cd3fc885f8beca3198c0385256c4..0cb746e38d448daee9bc40e243fd6363ae115e38 100644 (file)
@@ -1338,6 +1338,7 @@ void Model_Objects::removeFolder(std::shared_ptr<ModelAPI_Folder> theFolder)
   updateHistory(ModelAPI_Feature::group());
 }
 
+// Returns one of the limiting features of the list
 static FeaturePtr limitingFeature(std::list<FeaturePtr>& theFeatures, const bool isLast)
 {
   FeaturePtr aFeature;
@@ -1351,24 +1352,11 @@ static FeaturePtr limitingFeature(std::list<FeaturePtr>& 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<ModelAPI_CompositeFeature>(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<ModelAPI_Folder> Model_Objects::findFolder(
@@ -1383,9 +1371,9 @@ std::shared_ptr<ModelAPI_Folder> 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<std::shared_ptr<ModelAPI_Feature> > aFeatures = theFeatures;
   std::shared_ptr<ModelAPI_Feature> aLimitingFeature = limitingFeature(aFeatures, theBelow);
+
   std::shared_ptr<Model_Data> aData =
       std::static_pointer_cast<Model_Data>(aLimitingFeature->data());
   if (!aData || !aData->isValid())
@@ -1394,11 +1382,8 @@ std::shared_ptr<ModelAPI_Folder> 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<ModelAPI_Folder> 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<ModelAPI_Folder> 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<ModelAPI_Folder>(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<ModelAPI_Folder> 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<Model_Data>(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<Model_Data>(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<Model_Data> aData =
       std::static_pointer_cast<Model_Data>(theFolder->data());
   if (aData && aData->isValid())
     aFolderLabel = aData->label().Father();
-  FeaturePtr aLastFeature = theFeatures.back();
-  CompositeFeaturePtr aComposite =
-      std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aLastFeature);
-  if (aComposite)
-    aLastFeature = aComposite->subFeature(aComposite->numberOfSubs() - 1);
   aData = std::static_pointer_cast<Model_Data>(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<ModelAPI_CompositeFeature>(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;
 
index fb7cbf1c619f79e58fbd01f5eb92eb7f9922cece..bf6768a1ff0e0a29b80fca2240c46aad43c1f7bd 100644 (file)
@@ -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
 #=========================================================================