if (aPrevData.get()) {
aPrevFeateureLab = aPrevData->label().Father();
}
- // check if the previous feature is the last feature in a folder,
- // then the folder should be updated to contain additional feature
- aParentFolder = inFolder(theAfterThis, ModelAPI_Folder::LAST_FEATURE_ID());
+ // Check if the previous feature is the last feature in a folder,
+ // then the folder should be updated to contain additional feature.
+ // Macro features are not stored in folder.
+ if (!theFeature->isMacro()) {
+ // If the last feature is a sub-feature of composite, use parent feature
+ // to check belonging to a folder.
+ FeaturePtr afterThis = ModelAPI_Tools::compositeOwner(theAfterThis);
+ if (!afterThis)
+ afterThis = theAfterThis;
+ aParentFolder = inFolder(afterThis, ModelAPI_Folder::LAST_FEATURE_ID());
+ }
}
AddToRefArray(aFeaturesLab, aFeatureLab, aPrevFeateureLab);
} else {
// it may be a folder
- ObjectPtr aFolder = folder(aRefs->Value(a));
+ const ObjectPtr& aFolder = folder(aRefs->Value(a));
if (aFolder.get()) {
// store folder information for the Features group only
if (isFeature || isFolder) {
}
}
-ObjectPtr Model_Objects::folder(TDF_Label theLabel) const
+const ObjectPtr& Model_Objects::folder(TDF_Label theLabel) const
{
if (myFolders.IsBound(theLabel))
return myFolders.Find(theLabel);
- return ObjectPtr();
+ static ObjectPtr anEmptyResult;
+ return anEmptyResult;
}
FeaturePtr Model_Objects::feature(TDF_Label theLabel) const
} else aCurrentIter++;
}
}
+ // for the last feature in the folder, check if it is a sub-feature,
+ // then refer the folder to a top-level parent composite feature
+ const std::set<AttributePtr>& aRefs = aData->refsToMe();
+ std::set<AttributePtr>::iterator anIt = aRefs.begin();
+ for (; anIt != aRefs.end(); ++anIt)
+ if ((*anIt)->id() == ModelAPI_Folder::LAST_FEATURE_ID())
+ break;
+ if (anIt != aRefs.end()) {
+ FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
+ if (aFeature) {
+ CompositeFeaturePtr aParent;
+ CompositeFeaturePtr aGrandParent = ModelAPI_Tools::compositeOwner(aFeature);
+ do {
+ aParent = aGrandParent;
+ if (aGrandParent)
+ aGrandParent = ModelAPI_Tools::compositeOwner(aParent);
+ } while (aGrandParent.get());
+ if (aParent) {
+ ObjectPtr aFolder = (*anIt)->owner();
+ // remove reference from the current feature
+ aData->removeBackReference(aFolder, ModelAPI_Folder::LAST_FEATURE_ID());
+ // set reference to a top-level parent
+ aFolder->data()->reference(ModelAPI_Folder::LAST_FEATURE_ID())->setValue(aParent);
+ std::shared_ptr<Model_Data> aParentData =
+ std::dynamic_pointer_cast<Model_Data>(aParent->data());
+ aParentData->addBackReference(aFolder, ModelAPI_Folder::LAST_FEATURE_ID());
+ }
+ }
+ }
aData->updateConcealmentFlag();
}
continue;
}
- aFoundFolder = std::dynamic_pointer_cast<ModelAPI_Folder>(folder(aCurLabel));
- if (aFoundFolder) {
+ const ObjectPtr& aFolderObj = folder(aCurLabel);
+ if (aFolderObj.get()) {
+ aFoundFolder = std::dynamic_pointer_cast<ModelAPI_Folder>(aFolderObj);
AttributeReferencePtr aLastFeatAttr =
aFoundFolder->reference(ModelAPI_Folder::LAST_FEATURE_ID());
if (aLastFeatAttr) {
for (int aRefIndex = aRefs->Lower(); aRefIndex <= aRefs->Upper(); ++aRefIndex) {
TDF_Label aCurLabel = aRefs->Value(aRefIndex);
- if (isSkippedFeature(feature(aCurLabel)))
- continue;
if (aFoundFolder)
++theIndexInFolder;
- if (aCurLabel == aLabelToFind) // the feature is reached
+ if (aCurLabel == aLabelToFind) { // the feature is reached
+ if (aFoundFolder) {
+ if (isSkippedFeature(theFeature)) {
+ theIndexInFolder = -1;
+ return FolderPtr();
+ }
+ // decrease the index of the feature in the folder by the number of skipped features
+ for (int anIndex = theIndexInFolder - 1; anIndex > 0; anIndex--) {
+ aCurLabel = aRefs->Value(aRefIndex - anIndex);
+ if (isSkippedFeature(feature(aCurLabel)))
+ theIndexInFolder--;
+ }
+ }
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) {
+ const ObjectPtr& aFolderObj = folder(aCurLabel);
+ if (aFolderObj.get()) {
+ aFoundFolder = std::dynamic_pointer_cast<ModelAPI_Folder>(aFolderObj);
theIndexInFolder = -1;
AttributeReferencePtr aLastRef =
{
Handle(TDataStd_ReferenceArray) aRefs;
if (featuresLabel().FindAttribute(TDataStd_ReferenceArray::GetID(), aRefs)) {
+ FeaturePtr aLast = feature(aRefs->Value(aRefs->Upper()));
+ if (!aLast.get() && aRefs->Length() != 0) { // erase the invalid feature from the array
+ RemoveFromRefArray(featuresLabel(), aRefs->Value(aRefs->Upper()));
+ return lastFeature(); // try once again, after the last was removed
+ }
return feature(aRefs->Value(aRefs->Upper()));
}
return FeaturePtr(); // no features at all