+
+void Model_AttributeSelection::updateInHistory()
+{
+ ResultPtr aContext = std::dynamic_pointer_cast<ModelAPI_Result>(myRef.value());
+ // only bodies may be modified later in the history, don't do anything otherwise
+ if (!aContext.get() || aContext->groupName() != ModelAPI_ResultBody::group())
+ return;
+ std::shared_ptr<Model_Data> aContData = std::dynamic_pointer_cast<Model_Data>(aContext->data());
+ if (!aContData.get() || !aContData->isValid())
+ return;
+ TDF_Label aContLab = aContData->label(); // named shape where the selected context is located
+ Handle(TNaming_NamedShape) aContNS;
+ if (!aContLab.FindAttribute(TNaming_NamedShape::GetID(), aContNS))
+ return;
+ std::shared_ptr<Model_Document> aDoc =
+ std::dynamic_pointer_cast<Model_Document>(aContext->document());
+ FeaturePtr aThisFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(owner());
+ FeaturePtr aCurrentModifierFeat = aDoc->feature(aContext);
+ // iterate the context shape modifications in order to find a feature that is upper in history
+ // that this one and is really modifies the referenced result to refer to it
+ ResultPtr aModifierResFound;
+ TNaming_Iterator aPairIter(aContNS);
+ TopoDS_Shape aNewShape = aPairIter.NewShape();
+ bool anIterate = true;
+ // trying to update also the sub-shape selected
+ GeomShapePtr aSubShape = value();
+ if (aSubShape.get() && aSubShape->isEqual(aContext->shape()))
+ aSubShape.reset();
+
+ while(anIterate) {
+ anIterate = false;
+ TNaming_SameShapeIterator aModifIter(aNewShape, aContLab);
+ for(; aModifIter.More(); aModifIter.Next()) {
+ ResultPtr aModifierObj = std::dynamic_pointer_cast<ModelAPI_Result>
+ (aDoc->objects()->object(aModifIter.Label().Father()));
+ if (!aModifierObj.get())
+ break;
+ FeaturePtr aModifierFeat = aDoc->feature(aModifierObj);
+ if (!aModifierFeat.get())
+ break;
+ if (aModifierFeat == aThisFeature || aDoc->objects()->isLater(aModifierFeat, aThisFeature))
+ continue; // the modifier feature is later than this, so, should not be used
+ if (aCurrentModifierFeat == aModifierFeat || aDoc->objects()->isLater(aCurrentModifierFeat, aModifierFeat))
+ continue; // the current modifier is later than the found, so, useless
+ Handle(TNaming_NamedShape) aNewNS;
+ aModifIter.Label().FindAttribute(TNaming_NamedShape::GetID(), aNewNS);
+ if (aNewNS->Evolution() == TNaming_MODIFY || aNewNS->Evolution() == TNaming_GENERATED) {
+ aModifierResFound = aModifierObj;
+ aCurrentModifierFeat = aModifierFeat;
+ TNaming_Iterator aPairIter(aNewNS);
+ aNewShape = aPairIter.NewShape();
+ /*
+ // searching for sub-shape equivalent on the sub-label of the new context result
+ TDF_ChildIDIterator aNSIter(aNewNS->Label(), TNaming_NamedShape::GetID());
+ for(; aNSIter.More(); aNSIter.Next()) {
+ TNaming_Iterator aPairsIter(aNSIter.Value()->Label());
+ for(; aPairsIter.More(); aPairsIter.Next()) {
+ if (aSubShape->impl<TopoDS_Shape>().IsEqual()
+ }
+ }*/
+ anIterate = true;
+ break;
+ } else if (aNewNS->Evolution() == TNaming_DELETE) { // a shape was deleted => result is null
+ ResultPtr anEmptyContext;
+ std::shared_ptr<GeomAPI_Shape> anEmptyShape;
+ setValue(anEmptyContext, anEmptyShape); // nullify the selection
+ return;
+ } else { // not-precessed modification => don't support it
+ continue;
+ }
+ }
+
+ /*
+ TNaming_NewShapeIterator aModifIter(aPairIter.NewShape(), aContLab);
+ if (aModifIter.More()) aModifIter.Next(); // skip this shape result
+ for(; aModifIter.More(); aModifIter.Next()) {
+ ResultPtr aModifierObj = std::dynamic_pointer_cast<ModelAPI_Result>
+ (aDoc->objects()->object(aModifIter.Label().Father()));
+ if (!aModifierObj.get())
+ break;
+ FeaturePtr aModifierFeat = aDoc->feature(aModifierObj);
+ if (!aModifierFeat.get())
+ break;
+ if (aModifierFeat == aThisFeature || aDoc->objects()->isLater(aModifierFeat, aThisFeature))
+ break; // the modifier feature is later than this, so, should not be used
+ Handle(TNaming_NamedShape) aNewNS = aModifIter.NamedShape();
+ if (aNewNS->Evolution() == TNaming_MODIFY || aNewNS->Evolution() == TNaming_GENERATED) {
+ aModifierResFound = aModifierObj;
+ } else if (aNewNS->Evolution() == TNaming_DELETE) { // a shape was deleted => result is null
+ ResultPtr anEmptyContext;
+ std::shared_ptr<GeomAPI_Shape> anEmptyShape;
+ setValue(anEmptyContext, anEmptyShape); // nullify the selection
+ return;
+ } else { // not-precessed modification => don't support it
+ break;
+ }
+ }
+ // already found what is needed, don't iterate the next pair since normally
+ if (aModifierResFound.get()) // there must be only one pair in the result-shape
+ break;
+ */
+ }
+ if (aModifierResFound.get()) {
+ // update scope to reset to a new one
+ myScope.Clear();
+ myRef.setValue(aModifierResFound);
+ update(); // it must recompute a new sub-shape automatically
+ }
+ /*
+ if (aModifierResFound.get()) {
+ // update scope to reset to a new one
+ myScope.Clear();
+ if (!aSubShape.get() || aSubShape->isNull()) { // no sub-shape, so, just update a context
+ setValue(aModifierResFound, aSubShape);
+ return;
+ }
+ // seaching for the same sub-shape: the old topology stays the same
+ TopoDS_Shape anOldShape = aSubShape->impl<TopoDS_Shape>();
+ TopAbs_ShapeEnum aSubType = anOldShape.ShapeType();
+ TopoDS_Shape aNewContext = aModifierResFound->shape()->impl<TopoDS_Shape>();
+ TopExp_Explorer anExp(aNewContext, aSubType);
+ for(; anExp.More(); anExp.Next()) {
+ if (anExp.Current().IsEqual(anOldShape))
+ break;
+ }
+ if (anExp.More()) { // found
+ setValue(aModifierResFound, aSubShape);
+ return;
+ }
+ // seaching for the same sub-shape: equal geometry
+ for(anExp.Init(aNewContext, aSubType); anExp.More(); anExp.Next()) {
+ if (aSubType == TopAbs_VERTEX) {
+
+ }
+ }
+ }*/
+ // if sub-shape selection exists, search also sub-shape new instance
+ /*
+ GeomShapePtr aSubShape = value();
+ if (aSubShape.get() && aSubShape != aContext->shape()) {
+
+ }*/
+}