using namespace std;
Model_Update MY_UPDATER_INSTANCE; /// the only one instance initialized on load of the library
-#define DEB_UPDATE
+//#define DEB_UPDATE
Model_Update::Model_Update()
{
if ((*anObjIter)->groupName() == ModelAPI_ResultParameter::group()) {
myIsParamUpdated = true;
}
- // created objects are always must be up to date (python box feature)
- // and updated not in internal uptation chain
- myUpdated[*anObjIter] = myModification;
-
- // something is updated during the execution: re-execute it (sketch update by parameters or
- // Box macro that updates the upper features during the execution)
- if (myIsExecuted) {
- FeaturePtr anUpdated = std::dynamic_pointer_cast<ModelAPI_Feature>(*anObjIter);
- if (anUpdated.get() && anUpdated->data()->isValid())
- iterateUpdateBreak(anUpdated);
- }
- #ifdef DEB_UPDATE
- if (myIsExecuted) std::cout<<"During execution ";
- if ((*anObjIter)->data() && (*anObjIter)->data()->isValid()) {
- std::cout<<"add updated "<<(*anObjIter)->groupName()<<" "
- <<(*anObjIter)->data()->name()<<std::endl;
+ // on undo/redo, abort do not update persisten features
+ FeaturePtr anUpdated = std::dynamic_pointer_cast<ModelAPI_Feature>(*anObjIter);
+ if (std::dynamic_pointer_cast<Model_Document>((*anObjIter)->document())->executeFeatures() ||
+ (anUpdated.get() && !anUpdated->isPersistentResult())) {
+ // created objects are always must be up to date (python box feature)
+ // and updated not in internal uptation chain
+ myUpdated[*anObjIter] = myModification;
+
+ // something is updated during the execution: re-execute it (sketch update by parameters or
+ // Box macro that updates the upper features during the execution)
+ if (myIsExecuted) {
+ FeaturePtr anUpdated = std::dynamic_pointer_cast<ModelAPI_Feature>(*anObjIter);
+ if (anUpdated.get() && anUpdated->data()->isValid())
+ iterateUpdateBreak(anUpdated);
+ }
+#ifdef DEB_UPDATE
+ if (myIsExecuted) std::cout<<"During execution ";
+ if ((*anObjIter)->data() && (*anObjIter)->data()->isValid()) {
+ std::cout<<"add updated "<<(*anObjIter)->groupName()<<" "
+ <<(*anObjIter)->data()->name()<<std::endl;
+ }
+#endif
}
- #endif
+
}
// this event is for solver update, not here, do not react immediately
if (!isOnlyResults && !(theMessage->eventID() == kMovedEvent))
for(aFIter = myWaitForFinish.begin(); aFIter != myWaitForFinish.end(); aFIter++)
{
FeaturePtr aF = std::dynamic_pointer_cast<ModelAPI_Feature>(*aFIter);
- if (aF && aF->data()->isValid() && aF->getKind() == "Extrusion") {
+ if (aF && aF->data()->isValid() &&
+ (aF->getKind() == "Extrusion" || aF->getKind() == "Revolution")) {
AttributeSelectionListPtr aBase = aF->selectionList("base");
if (aBase.get()) {
for(int a = aBase->size() - 1; a >= 0; a--) {
CompositeFeaturePtr aCompos = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(theFeature);
// If automatice update is not needed and feature attributes were not updated right now,
// do not execute it and do not update arguments.
- if (!myIsAutomatic && myUpdated.find(theFeature) == myUpdated.end() && !aCompos.get()) {
+ if (!myIsAutomatic &&
+ (myUpdated.find(theFeature) == myUpdated.end() || myUpdated[theFeature] != myModification)
+ && !aCompos.get()) {
// execute will be performed later, but some features may have not-result
// presentations, so call update for them (like coincidence in the sketcher)
static Events_ID EVENT_DISP = Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY);
return;
}
+ // only the currently updated features are executed
bool aJustUpdated = myUpdated.find(theFeature) != myUpdated.end();
+ if (aJustUpdated) {
+ // if preview is not needed, the created feature was not updated before, so, myModification is not actual for this
+ if (theFeature->isPreviewNeeded()) {
+ aJustUpdated = myUpdated[theFeature] == myModification;
+ }
+ }
if (myIsAutomatic && theFeature->data()->execState() == ModelAPI_StateMustBeUpdated)
aJustUpdated = true;
if (theFeature->data()->execState() == ModelAPI_StateMustBeUpdated) { // it is done (in the tree)
theFeature->data()->execState(ModelAPI_StateDone);
}
+ // it will be not updated with new modifications: only the currently updated features are updated
+ //if (myUpdated.find(theFeature) != myUpdated.end()) {
+ // myUpdated.erase(theFeature); // do not update this persistent feature even in the future
+ //}
}
return;
}
aRes->data()->setUpdateID(theFeature->data()->updateID());
}
ModelAPI_EventCreator::get()->sendUpdated(aRes, EVENT_DISP);
+ // iterate sub-bodies of compsolid
+ ResultCompSolidPtr aComp = std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(aRes);
+ if (aComp.get()) {
+ int aNumSub = aComp->numberOfSubs();
+ for(int a = 0; a < aNumSub; a++) {
+ ResultPtr aSub = aComp->subResult(a);
+ if (!aSub->isDisabled()) {// update state only for enabled results (Placement Result Part may make the original Part Result as invalid)
+ aSub->data()->execState(theState);
+ if (theState == ModelAPI_StateDone) // feature become "done", so execution changed results
+ myUpdated[aSub] = myModification;
+ }
+ if (theFeature->data()->updateID() > aSub->data()->updateID()) {
+ aSub->data()->setUpdateID(theFeature->data()->updateID());
+ }
+ ModelAPI_EventCreator::get()->sendUpdated(aSub, EVENT_DISP);
+ }
+ }
}
// to redisplay "presentable" feature (for ex. distance constraint)
ModelAPI_EventCreator::get()->sendUpdated(theFeature, EVENT_DISP);