- // iterate groups labels
- TDF_ChildIDIterator aGroupsIter(myDoc->Main().FindChild(TAG_OBJECTS),
- TDataStd_Comment::GetID(), Standard_False);
- vector<string>::iterator aGroupNamesIter = myGroupsNames.begin();
- for(; aGroupsIter.More() && aGroupNamesIter != myGroupsNames.end();
- aGroupsIter.Next(), aGroupNamesIter++) {
- string aGroupName = TCollection_AsciiString(Handle(TDataStd_Comment)::DownCast(
- aGroupsIter.Value())->Get()).ToCString();
- if (*aGroupNamesIter != aGroupName)
- break; // all since there is a change this must be recreated from scratch
- }
- // delete all groups left after the data model groups iteration
- while(aGroupNamesIter != myGroupsNames.end()) {
- string aGroupName = *aGroupNamesIter;
- myFeatures.erase(aGroupName);
- myGroups.erase(aGroupName);
- aGroupNamesIter = myGroupsNames.erase(aGroupNamesIter);
- // say that features were deleted from group
- ModelAPI_FeatureDeletedMessage aMsg(aThis, aGroupName);
- Events_Loop::loop()->send(aMsg);
- }
- // create new groups basing on the following data model update
- for(; aGroupsIter.More(); aGroupsIter.Next()) {
- string aGroupName = TCollection_AsciiString(Handle(TDataStd_Comment)::DownCast(
- aGroupsIter.Value())->Get()).ToCString();
- myGroupsNames.push_back(aGroupName);
- myGroups[aGroupName] = aGroupsIter.Value()->Label();
- myFeatures[aGroupName] = vector<boost::shared_ptr<ModelAPI_Feature> >();
- }
- // update features group by group
- aGroupsIter.Initialize(myDoc->Main().FindChild(TAG_OBJECTS),
- TDataStd_Comment::GetID(), Standard_False);
- for(; aGroupsIter.More(); aGroupsIter.Next()) {
- string aGroupName = TCollection_AsciiString(Handle(TDataStd_Comment)::DownCast(
- aGroupsIter.Value())->Get()).ToCString();
- // iterate features in internal container
- vector<boost::shared_ptr<ModelAPI_Feature> >& aFeatures = myFeatures[aGroupName];
- vector<boost::shared_ptr<ModelAPI_Feature> >::iterator aFIter = aFeatures.begin();
- // and in parallel iterate labels of features
- TDF_ChildIDIterator aFLabIter(
- aGroupsIter.Value()->Label(), TDataStd_Comment::GetID(), Standard_False);
- while(aFIter != aFeatures.end() || aFLabIter.More()) {
- static const int INFINITE_TAG = INT_MAX; // no label means that it exists somwhere in infinite
- int aFeatureTag = INFINITE_TAG;
- if (aFIter != aFeatures.end()) { // existing tag for feature
- boost::shared_ptr<Model_Data> aData = boost::dynamic_pointer_cast<Model_Data>((*aFIter)->data());
- aFeatureTag = aData->label().Tag();
- }
- int aDSTag = INFINITE_TAG;
- if (aFLabIter.More()) { // next label in DS is existing
- aDSTag = aFLabIter.Value()->Label().Tag();
- }
- if (aDSTag > aFeatureTag) { // feature is removed
- aFIter = aFeatures.erase(aFIter);
- // event: model is updated
- ModelAPI_FeatureDeletedMessage aMsg(aThis, aGroupName);
- Events_Loop::loop()->send(aMsg);
- } else if (aDSTag < aFeatureTag) { // a new feature is inserted
- // create a feature
- boost::shared_ptr<ModelAPI_Feature> aFeature = ModelAPI_PluginManager::get()->createFeature(
- TCollection_AsciiString(Handle(TDataStd_Comment)::DownCast(
- aFLabIter.Value())->Get()).ToCString());
-
- boost::shared_ptr<Model_Data> aData(new Model_Data);
- TDF_Label aLab = aFLabIter.Value()->Label();
- aData->setLabel(aLab);
- aData->setDocument(Model_Application::getApplication()->getDocument(myID));
- aFeature->setData(aData);
- aFeature->initAttributes();
- // event: model is updated
- static Events_ID anEvent = Events_Loop::eventByName(EVENT_FEATURE_CREATED);
- ModelAPI_FeatureUpdatedMessage aMsg(aThis, aFeature, anEvent);
- Events_Loop::loop()->send(aMsg);
-
- if (aFIter == aFeatures.end()) {
- aFeatures.push_back(aFeature);
- aFIter = aFeatures.end();
- } else {
- aFIter++;
- aFeatures.insert(aFIter, aFeature);
- }
- // feature for this label is added, so go to the next label
- aFLabIter.Next();
- } else { // nothing is changed, both iterators are incremented
+ // update features
+ vector<boost::shared_ptr<ModelAPI_Feature> >::iterator aFIter = myFeatures.begin();
+ // and in parallel iterate labels of features
+ TDF_ChildIDIterator aFLabIter(groupLabel(FEATURES_GROUP), TDataStd_Comment::GetID());
+ while(aFIter != myFeatures.end() || aFLabIter.More()) {
+ static const int INFINITE_TAG = INT_MAX; // no label means that it exists somwhere in infinite
+ int aFeatureTag = INFINITE_TAG;
+ if (aFIter != myFeatures.end()) { // existing tag for feature
+ boost::shared_ptr<Model_Data> aData = boost::dynamic_pointer_cast<Model_Data>((*aFIter)->data());
+ aFeatureTag = aData->label().Tag();
+ }
+ int aDSTag = INFINITE_TAG;
+ if (aFLabIter.More()) { // next label in DS is existing
+ aDSTag = aFLabIter.Value()->Label().Tag();
+ }
+ if (aDSTag > aFeatureTag) { // feature is removed
+ Model_FeatureDeletedMessage aMsg1(aThis, FEATURES_GROUP);
+ Model_FeatureDeletedMessage aMsg2(aThis, (*aFIter)->getGroup());
+ aFIter = myFeatures.erase(aFIter);
+ // event: model is updated
+ Events_Loop::loop()->send(aMsg1);
+ Events_Loop::loop()->send(aMsg2);
+ } else if (aDSTag < aFeatureTag) { // a new feature is inserted
+ // create a feature
+ boost::shared_ptr<ModelAPI_Feature> aFeature = ModelAPI_PluginManager::get()->createFeature(
+ TCollection_AsciiString(Handle(TDataStd_Comment)::DownCast(
+ aFLabIter.Value())->Get()).ToCString());
+
+ if (aFIter == myFeatures.end()) { // must be before "setData" to redo the sketch line correctly
+ myFeatures.push_back(aFeature);
+ aFIter = myFeatures.end();
+ } else {