- boost::shared_ptr<ModelAPI_Document> aThis =
- Model_Application::getApplication()->getDocument(myID);
- TDF_Label aFeaturesLab = groupLabel(FEATURES_GROUP);
- TDF_Label aFeatureLab = aFeaturesLab.NewChild();
-
- // organize feature and data objects
- boost::shared_ptr<Model_Data> aData(new Model_Data);
- aData->setFeature(theFeature);
- aData->setLabel(aFeatureLab);
- theFeature->setDoc(aThis);
- theFeature->setData(aData);
- setUniqueName(theFeature);
- theFeature->initAttributes();
-
- // keep the feature ID to restore document later correctly
- TDataStd_Comment::Set(aFeatureLab, theFeature->getKind().c_str());
- myFeatures.push_back(theFeature);
- // store feature in the history of features array
- if (theFeature->isInHistory()) {
- AddToRefArray(aFeaturesLab, aFeatureLab);
- }
- // add featue to the group
- const std::string& aGroup = theFeature->getGroup();
- TDF_Label aGroupLab = groupLabel(aGroup);
- AddToRefArray(aGroupLab, aFeatureLab);
- // new name of this feature object by default equal to name of feature
- TDF_Label anObjLab = aGroupLab.NewChild();
- TCollection_ExtendedString aName(theFeature->data()->getName().c_str());
- TDataStd_Name::Set(anObjLab, aName);
- AddToRefArray(aGroupLab.FindChild(1), anObjLab); // reference to names is on the first sub
-
- // event: feature is added
- static Events_ID anEvent = Events_Loop::eventByName(EVENT_FEATURE_CREATED);
- Model_FeatureUpdatedMessage aMsg(theFeature, anEvent);
- Events_Loop::loop()->send(aMsg);
-}
-
-boost::shared_ptr<ModelAPI_Feature> Model_Document::feature(TDF_Label& theLabel)
-{
- // iterate all features, may be optimized later by keeping labels-map
- vector<boost::shared_ptr<ModelAPI_Feature> >::iterator aFIter = myFeatures.begin();
- for(; aFIter != myFeatures.end(); aFIter++) {
- boost::shared_ptr<Model_Data> aData =
- boost::dynamic_pointer_cast<Model_Data>((*aFIter)->data());
- if (aData->label().IsEqual(theLabel))
- return *aFIter;
- }
- return boost::shared_ptr<ModelAPI_Feature>(); // not found
-}
-
-boost::shared_ptr<ModelAPI_Document> Model_Document::subDocument(string theDocID)
+ TDF_Label anEmptyLab;
+ FeaturePtr anEmptyFeature;
+ FeaturePtr aFeature = ModelAPI_Session::get()->createFeature(theID);
+ if (!aFeature)
+ return aFeature;
+ std::shared_ptr<Model_Document> aDocToAdd = std::dynamic_pointer_cast<Model_Document>(
+ aFeature->documentToAdd());
+ if (aFeature) {
+ TDF_Label aFeatureLab;
+ if (!aFeature->isAction()) { // do not add action to the data model
+ TDF_Label aFeaturesLab = aDocToAdd->featuresLabel();
+ aFeatureLab = aFeaturesLab.NewChild();
+ aDocToAdd->initData(aFeature, aFeatureLab, TAG_FEATURE_ARGUMENTS);
+ // keep the feature ID to restore document later correctly
+ TDataStd_Comment::Set(aFeatureLab, aFeature->getKind().c_str());
+ aDocToAdd->myObjs.Bind(aFeatureLab, aFeature);
+ // store feature in the history of features array
+ if (aFeature->isInHistory()) {
+ AddToRefArray(aFeaturesLab, aFeatureLab);
+ }
+ }
+ if (!aFeature->isAction()) { // do not add action to the data model
+ // event: feature is added
+ static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_CREATED);
+ ModelAPI_EventCreator::get()->sendUpdated(aFeature, anEvent);
+ } else { // feature must be executed
+ // no creation event => updater not working, problem with remove part
+ aFeature->execute();
+ }
+ }
+ return aFeature;
+}
+
+/// Appenad to the array of references a new referenced label.
+/// If theIndex is not -1, removes element at thisindex, not theReferenced.
+/// \returns the index of removed element
+static int RemoveFromRefArray(TDF_Label theArrayLab, TDF_Label theReferenced, const int theIndex =
+ -1)
+{
+ int aResult = -1; // no returned
+ Handle(TDataStd_ReferenceArray) aRefs;
+ if (theArrayLab.FindAttribute(TDataStd_ReferenceArray::GetID(), aRefs)) {
+ if (aRefs->Length() == 1) { // just erase an array
+ if ((theIndex == -1 && aRefs->Value(0) == theReferenced) || theIndex == 0) {
+ theArrayLab.ForgetAttribute(TDataStd_ReferenceArray::GetID());
+ }
+ aResult = 0;
+ } else { // reduce the array
+ Handle(TDataStd_HLabelArray1) aNewArray = new TDataStd_HLabelArray1(aRefs->Lower(),
+ aRefs->Upper() - 1);
+ int aCount = aRefs->Lower();
+ for (int a = aCount; a <= aRefs->Upper(); a++, aCount++) {
+ if ((theIndex == -1 && aRefs->Value(a) == theReferenced) || theIndex == a) {
+ aCount--;
+ aResult = a;
+ } else {
+ aNewArray->SetValue(aCount, aRefs->Value(a));
+ }
+ }
+ aRefs->SetInternalArray(aNewArray);
+ }
+ }
+ return aResult;
+}
+
+void Model_Document::removeFeature(FeaturePtr theFeature, const bool theCheck)
+{
+ if (theCheck) {
+ // check the feature: it must have no depended objects on it
+ std::list<ResultPtr>::const_iterator aResIter = theFeature->results().cbegin();
+ for(; aResIter != theFeature->results().cend(); aResIter++) {
+ std::shared_ptr<Model_Data> aData =
+ std::dynamic_pointer_cast<Model_Data>((*aResIter)->data());
+ if (aData && !aData->refsToMe().empty()) {
+ Events_Error::send(
+ "Feature '" + theFeature->data()->name() + "' is used and can not be deleted");
+ return;
+ }
+ }
+ }
+
+ std::shared_ptr<Model_Data> aData = std::static_pointer_cast<Model_Data>(theFeature->data());
+ if (aData) {
+ TDF_Label aFeatureLabel = aData->label().Father();
+ if (myObjs.IsBound(aFeatureLabel))
+ myObjs.UnBind(aFeatureLabel);
+ else
+ return; // not found feature => do not remove
+ // erase fields
+ theFeature->erase();
+ // erase all attributes under the label of feature
+ aFeatureLabel.ForgetAllAttributes();
+ // remove it from the references array
+ if (theFeature->isInHistory()) {
+ RemoveFromRefArray(featuresLabel(), aFeatureLabel);
+ }
+ }
+ // event: feature is deleted
+ ModelAPI_EventCreator::get()->sendDeleted(theFeature->document(), ModelAPI_Feature::group());
+}
+
+FeaturePtr Model_Document::feature(TDF_Label& theLabel)
+{
+ if (myObjs.IsBound(theLabel))
+ return myObjs.Find(theLabel);
+ return FeaturePtr(); // not found
+}
+
+ObjectPtr Model_Document::object(TDF_Label theLabel)
+{
+ // try feature by label
+ FeaturePtr aFeature = feature(theLabel);
+ if (aFeature)
+ return feature(theLabel);
+ TDF_Label aFeatureLabel = theLabel.Father().Father(); // let's suppose it is result
+ aFeature = feature(aFeatureLabel);
+ if (aFeature) {
+ const std::list<std::shared_ptr<ModelAPI_Result> >& aResults = aFeature->results();
+ std::list<std::shared_ptr<ModelAPI_Result> >::const_iterator aRIter = aResults.cbegin();
+ for (; aRIter != aResults.cend(); aRIter++) {
+ std::shared_ptr<Model_Data> aResData = std::dynamic_pointer_cast<Model_Data>(
+ (*aRIter)->data());
+ if (aResData->label().Father().IsEqual(theLabel))
+ return *aRIter;
+ }
+ }
+ return FeaturePtr(); // not found
+}
+
+std::shared_ptr<ModelAPI_Document> Model_Document::subDocument(std::string theDocID)