+ static Model_ValidatorsFactory* aValidators =
+ static_cast<Model_ValidatorsFactory*>(ModelAPI_Session::get()->validators());
+ FeaturePtr aMyFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(myObject);
+
+ std::map<std::string, std::shared_ptr<ModelAPI_Attribute> >::iterator anAttr = myAttrs.begin();
+ std::list<ObjectPtr> aReferenced; // not inside of cycle to avoid excess memory management
+ for(; anAttr != myAttrs.end(); anAttr++) {
+ // skip not-case attributes, that really may refer to anything not-used (issue 671)
+ if (aMyFeature.get() && !aValidators->isCase(aMyFeature, anAttr->second->id()))
+ continue;
+
+ std::string aType = anAttr->second->attributeType();
+ if (aType == ModelAPI_AttributeReference::typeId()) { // reference to object
+ std::shared_ptr<ModelAPI_AttributeReference> aRef = std::dynamic_pointer_cast<
+ ModelAPI_AttributeReference>(anAttr->second);
+ aReferenced.push_back(aRef->value());
+ } else if (aType == ModelAPI_AttributeRefAttr::typeId()) { // reference to attribute or object
+ std::shared_ptr<ModelAPI_AttributeRefAttr> aRef = std::dynamic_pointer_cast<
+ ModelAPI_AttributeRefAttr>(anAttr->second);
+ if (aRef->isObject()) {
+ aReferenced.push_back(aRef->object());
+ } else {
+ AttributePtr anAttr = aRef->attr();
+ if (anAttr.get())
+ aReferenced.push_back(anAttr->owner());
+ }
+ } else if (aType == ModelAPI_AttributeRefList::typeId()) { // list of references
+ aReferenced = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(anAttr->second)->list();
+ } else if (aType == ModelAPI_AttributeSelection::typeId()) { // selection attribute
+ std::shared_ptr<ModelAPI_AttributeSelection> aRef = std::dynamic_pointer_cast<
+ ModelAPI_AttributeSelection>(anAttr->second);
+ aReferenced.push_back(aRef->context());
+ } else if (aType == ModelAPI_AttributeSelectionList::typeId()) { // list of selection attributes
+ std::shared_ptr<ModelAPI_AttributeSelectionList> aRef = std::dynamic_pointer_cast<
+ ModelAPI_AttributeSelectionList>(anAttr->second);
+ for(int a = aRef->size() - 1; a >= 0; a--) {
+ aReferenced.push_back(aRef->value(a)->context());
+ }
+ } else if (aType == ModelAPI_AttributeRefAttrList::typeId()) {
+ std::shared_ptr<ModelAPI_AttributeRefAttrList> aRefAttr = std::dynamic_pointer_cast<
+ ModelAPI_AttributeRefAttrList>(anAttr->second);
+ std::list<std::pair<ObjectPtr, AttributePtr> > aRefs = aRefAttr->list();
+ std::list<std::pair<ObjectPtr, AttributePtr> >::const_iterator anIt = aRefs.begin(),
+ aLast = aRefs.end();
+ for (; anIt != aLast; anIt++) {
+ aReferenced.push_back(anIt->first);
+ }
+ } else if (aType == ModelAPI_AttributeInteger::typeId()) { // integer attribute
+ AttributeIntegerPtr anAttribute =
+ std::dynamic_pointer_cast<ModelAPI_AttributeInteger>(anAttr->second);
+ std::set<std::string> anUsedParameters = anAttribute->usedParameters();
+ std::list<ResultParameterPtr> aParameters = findVariables(anUsedParameters);
+ aReferenced.insert(aReferenced.end(), aParameters.begin(), aParameters.end());
+ } else if (aType == ModelAPI_AttributeDouble::typeId()) { // double attribute
+ AttributeDoublePtr anAttribute =
+ std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(anAttr->second);
+ std::set<std::string> anUsedParameters = anAttribute->usedParameters();
+ std::list<ResultParameterPtr> aParameters = findVariables(anUsedParameters);
+ aReferenced.insert(aReferenced.end(), aParameters.begin(), aParameters.end());
+ } else if (aType == GeomDataAPI_Point::typeId()) { // point attribute
+ AttributePointPtr anAttribute =
+ std::dynamic_pointer_cast<GeomDataAPI_Point>(anAttr->second);
+ std::set<std::string> anUsedParameters = usedParameters(anAttribute);
+ std::list<ResultParameterPtr> aParameters = findVariables(anUsedParameters);
+ aReferenced.insert(aReferenced.end(), aParameters.begin(), aParameters.end());
+ } else if (aType == GeomDataAPI_Point2D::typeId()) { // point attribute
+ AttributePoint2DPtr anAttribute =
+ std::dynamic_pointer_cast<GeomDataAPI_Point2D>(anAttr->second);
+ std::set<std::string> anUsedParameters = usedParameters(anAttribute);
+ std::list<ResultParameterPtr> aParameters = findVariables(anUsedParameters);
+ aReferenced.insert(aReferenced.end(), aParameters.begin(), aParameters.end());
+ } else
+ continue; // nothing to do, not reference
+
+ if (!aReferenced.empty()) {
+ theRefs.push_back(std::pair<std::string, std::list<ObjectPtr> >(anAttr->first, aReferenced));
+ aReferenced.clear();
+ }
+ }
+}
+
+/// makes copy of all attributes on the given label and all sub-labels
+static void copyAttrs(TDF_Label theSource, TDF_Label theDestination) {
+ TDF_AttributeIterator anAttrIter(theSource);
+ for(; anAttrIter.More(); anAttrIter.Next()) {
+ Handle(TDF_Attribute) aTargetAttr;
+ if (!theDestination.FindAttribute(anAttrIter.Value()->ID(), aTargetAttr)) {
+ // create a new attribute if not yet exists in the destination
+ aTargetAttr = anAttrIter.Value()->NewEmpty();
+ theDestination.AddAttribute(aTargetAttr);
+ }
+ // no special relocation, empty map, but self-relocation is on: copy references w/o changes
+ Handle(TDF_RelocationTable) aRelocTable = new TDF_RelocationTable(Standard_True);
+ anAttrIter.Value()->Paste(aTargetAttr, aRelocTable);
+ }
+ // copy the sub-labels content
+ TDF_ChildIterator aSubLabsIter(theSource);
+ for(; aSubLabsIter.More(); aSubLabsIter.Next()) {
+ copyAttrs(aSubLabsIter.Value(), theDestination.FindChild(aSubLabsIter.Value().Tag()));
+ }
+}
+
+void Model_Data::copyTo(std::shared_ptr<ModelAPI_Data> theTarget)
+{
+ TDF_Label aTargetRoot = std::dynamic_pointer_cast<Model_Data>(theTarget)->label();
+ copyAttrs(myLab, aTargetRoot);
+ // reinitialize Model_Attributes by TDF_Attributes set
+ std::shared_ptr<Model_Data> aTData = std::dynamic_pointer_cast<Model_Data>(theTarget);
+ aTData->myAttrs.clear();
+ theTarget->owner()->initAttributes(); // reinit feature attributes
+}
+
+bool Model_Data::isInHistory()
+{
+ return myFlags->Value(kFlagInHistory) == Standard_True;
+}
+
+void Model_Data::setIsInHistory(const bool theFlag)
+{
+ return myFlags->SetValue(kFlagInHistory, theFlag);
+}
+
+bool Model_Data::isDeleted()
+{
+ return myFlags->Value(kFlagDeleted) == Standard_True;
+}
+
+void Model_Data::setIsDeleted(const bool theFlag)
+{
+ return myFlags->SetValue(kFlagDeleted, theFlag);
+}
+
+bool Model_Data::isDisplayed()
+{
+ if (!myObject.get() || !myObject->document().get() || // object is in valid
+ myFlags->Value(kFlagDisplayed) != Standard_True) // or it was not displayed before
+ return false;
+ if (myObject->document()->isActive()) // for active documents it must be ok anyway
+ return true;
+ // any object from the root document except part result may be displayed
+ if (myObject->document() == ModelAPI_Session::get()->moduleDocument() &&
+ myObject->groupName() != ModelAPI_ResultPart::group())
+ return true;
+ return false;
+}
+
+void Model_Data::setDisplayed(const bool theDisplay)
+{
+ if (theDisplay != isDisplayed()) {
+ myFlags->SetValue(kFlagDisplayed, theDisplay);
+ static Events_Loop* aLoop = Events_Loop::loop();
+ static Events_ID EVENT_DISP = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY);
+ static const ModelAPI_EventCreator* aECreator = ModelAPI_EventCreator::get();
+ aECreator->sendUpdated(myObject, EVENT_DISP);