-// Copyright (C) 2014-2020 CEA/DEN, EDF R&D
+// Copyright (C) 2014-2023 CEA/DEN, EDF R&D
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
#include <Model_Document.h>
#include <Model_Data.h>
#include <Model_Objects.h>
-#include <Model_AttributeSelection.h>
#include <ModelAPI_Feature.h>
#include <ModelAPI_Data.h>
#include <ModelAPI_Document.h>
Model_Update MY_UPDATER_INSTANCE; /// the only one instance initialized on load of the library
//#define DEB_UPDATE
+#ifdef DEB_UPDATE
+#include <Locale_Convert.h>
+#endif
+
Model_Update::Model_Update()
{
Events_Loop* aLoop = Events_Loop::loop();
else if (myProcessOnFinish.find(theFeature) == myProcessOnFinish.end())
myProcessOnFinish[theFeature] = std::set<std::shared_ptr<ModelAPI_Feature> >();
#ifdef DEB_UPDATE
- std::cout<<"*** Add process on finish "<<theFeature->name()<<std::endl;
+ std::wcout<<L"*** Add process on finish "<<theFeature->name()<<std::endl;
#endif
// keeps the currently updated features to avoid infinitive cycling here: where feature on
// "updateArguments" sends "updated" (in selection attribute) and goes here again
#endif
}
// clear processed and fill modified recursively
+ std::set<FeaturePtr> aRefSet;
const std::set<std::shared_ptr<ModelAPI_Attribute> >& aRefs = theFeature->data()->refsToMe();
std::set<std::shared_ptr<ModelAPI_Attribute> >::const_iterator aRefIter = aRefs.cbegin();
for(; aRefIter != aRefs.cend(); aRefIter++) {
if ((*aRefIter)->isArgument()) {
FeaturePtr aReferenced = std::dynamic_pointer_cast<ModelAPI_Feature>((*aRefIter)->owner());
if (aReferenced.get()) {
- addModified(aReferenced, theFeature);
+ aRefSet.insert(aReferenced);
}
}
}
if ((*aRIter)->isArgument()) {
FeaturePtr aReferenced = std::dynamic_pointer_cast<ModelAPI_Feature>((*aRIter)->owner());
if (aReferenced.get()) {
- addModified(aReferenced, theFeature);
+ aRefSet.insert(aReferenced);
}
}
}
}
-
// also add part feature that contains this feature to the modified
if (theFeature->document()->kind() != "PartSet") {
FeaturePtr aPart = ModelAPI_Tools::findPartFeature(
ModelAPI_Session::get()->moduleDocument(), theFeature->document());
if (aPart.get())
- addModified(aPart, theFeature);
+ aRefSet.insert(aPart);
}
+ for(std::set<FeaturePtr>::iterator aRef = aRefSet.begin(); aRef != aRefSet.end(); aRef++)
+ addModified(*aRef, theFeature);
+
return true;
}
if (!(*anObjIter)->data()->isValid())
continue;
#ifdef DEB_UPDATE
- std::cout<<">>> in event updated "<<(*anObjIter)->groupName()<<
- " "<<(*anObjIter)->data()->name()<<std::endl;
+ std::wcout<<L">>> in event updated "<<Locale::Convert::toWString((*anObjIter)->groupName())
+ <<L" "<<(*anObjIter)->data()->name()<<std::endl;
#endif
if ((*anObjIter)->groupName() == ModelAPI_ResultParameter::group()) {
myIsParamUpdated = true;
if (anUpdated.get()) {
if (addModified(anUpdated, FeaturePtr()))
aSomeModified = true;
- if (myUpdateBlocked) { // execute this feature anyway to show the current result
- /*if (!anUpdated->isStable() && anUpdated->results().size() && (
- anUpdated->firstResult()->groupName() == ModelAPI_ResultBody::group() ||
- anUpdated->firstResult()->groupName() == ModelAPI_ResultPart::group())) {
- if (aFactory->validate(anUpdated)) {
- executeFeature(anUpdated);
- redisplayWithResults(anUpdated, ModelAPI_StateNothing, false);
- static Events_ID EVENT_DISP = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY);
- aLoop->flush(EVENT_DISP);
- }
- }*/
- }
} else {
// process the updated result as update of features that refers to this result
const std::set<std::shared_ptr<ModelAPI_Attribute> >&
}
#ifdef DEB_UPDATE
- std::cout<<"* Process feature "<<theFeature->name()<<std::endl;
+ std::wcout<<L"* Process feature "<<theFeature->name()<<std::endl;
#endif
// update the sketch plane before the sketch sub-elements are recomputed
// (otherwise sketch will update plane, modify subs, after executed, but with old subs edges)
if (aIsModified && theFeature->getKind() == "Sketch") {
#ifdef DEB_UPDATE
- std::cout << "****** Update sketch args " << theFeature->name() << std::endl;
+ std::wcout << L"****** Update sketch args " << theFeature->name() << std::endl;
#endif
AttributeSelectionPtr anExtSel = theFeature->selection("External");
if (anExtSel.get()) {
}
#ifdef DEB_UPDATE
- std::cout<<"Update args "<<theFeature->name()<<std::endl;
+ std::wcout<<L"Update args "<<theFeature->name()<<std::endl;
#endif
// TestImport.py : after arguments are updated, theFeature may be removed
if (!theFeature->data()->isValid())
// don't disable Part because it will make disabled all the features
// (performance and problems with the current feature)
#ifdef DEB_UPDATE
- std::cout<<"Invalid args "<<theFeature->name()<<std::endl;
+ std::wcout<<L"Invalid args "<<theFeature->name()<<std::endl;
#endif
theFeature->eraseResults(false);
redisplayWithResults(theFeature, ModelAPI_StateInvalidArgument); // result also must be updated
if (!isPostponedMain) {
bool aDoExecute = true;
if (myUpdateBlocked) {
- if (!theFeature->isStable()) {
+ if (!theFeature->isStable() || (theFeature->getKind().size() > 6 &&
+ theFeature->getKind().substr(0, 6) == "Sketch")) { // automatic update sketch elements
aDoExecute = true;
} else if (theFeature->results().size()) { // execute only not persistent results features
aDoExecute = !theFeature->isPersistentResult();
}
} else {
#ifdef DEB_UPDATE
- std::cout<<"Feature is not valid, erase results "<<theFeature->name()<<std::endl;
+ std::wcout<<L"Feature is not valid, erase results "<<theFeature->name()<<std::endl;
#endif
theFeature->eraseResults(false);
redisplayWithResults(theFeature, ModelAPI_StateInvalidArgument); // result also must be updated
bool isObligatory = !aFactory->isNotObligatory(
theFeature->getKind(), theFeature->data()->id(aSel)) &&
aFactory->isCase(theFeature, theFeature->data()->id(aSel));
- if (isObligatory)
+ if (isObligatory ||
+ // #24260 : sketch plane was selected, but selection becomes wrong, make it invalid
+ (theFeature->getKind() == "Sketch" && aSel->id() == "External"))
aState = ModelAPI_StateInvalidArgument;
}
}
bool isObligatory = aFactory->isCase(theFeature, theFeature->data()->id(aSel));
if (isObligatory)
aState = ModelAPI_StateInvalidArgument;
- } else if (theFeature->getKind() == "Sketch" && aSel->id() == "External" &&
- aSel->isInitialized()) {
+ } else if (aSel->isInitialized()) {
// #19703 : if sketch plane was selected, but after context disappears, it must become invalid
aSel->update();
if (aSel->isInvalid()) {
void Model_Update::executeFeature(FeaturePtr theFeature)
{
#ifdef DEB_UPDATE
- std::cout<<"Execute Feature "<<theFeature->name()<<std::endl;
+ std::wcout<<L"Execute Feature "<<theFeature->name()<<std::endl;
#endif
// execute in try-catch to avoid internal problems of the feature
ModelAPI_ExecState aState = ModelAPI_StateDone;
(*anObj)->data()->attributes(ModelAPI_AttributeSelection::typeId());
std::list<AttributePtr>::iterator aRefsIter = aRefs.begin();
for (; aRefsIter != aRefs.end(); aRefsIter++) {
- std::shared_ptr<Model_AttributeSelection> aSel =
- std::dynamic_pointer_cast<Model_AttributeSelection>(*aRefsIter);
+ AttributeSelectionPtr aSel =
+ std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(*aRefsIter);
bool aRemove = false;
aSel->updateInHistory(aRemove);
}
std::shared_ptr<ModelAPI_AttributeSelectionList> aSel =
std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(*aRefsIter);
for(int a = aSel->size() - 1; a >= 0; a--) {
- std::shared_ptr<Model_AttributeSelection> aSelAttr =
- std::dynamic_pointer_cast<Model_AttributeSelection>(aSel->value(a));
+ AttributeSelectionPtr aSelAttr =
+ std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(aSel->value(a));
if (aSelAttr.get()) {
- bool theRemove = false;
- aSelAttr->updateInHistory(theRemove);
- if (theRemove) {
+ bool aRemove = false;
+ aSelAttr->updateInHistory(aRemove);
+ if (aRemove) {
aRemoveSet.insert(a);
}
}