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;
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(
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())
// 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();
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
}
}
- // 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
!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
}
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();
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)
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;
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)
aSession = ModelAPI_Session.get()
aPartDoc = aSession.activeDocument()
-
#=========================================================================
# Test 1. Sketch and extrusion could be added to the folder above
#=========================================================================