- std::set<FeaturePtr> alreadyProcessed; // features that are processed before others
- // all features one by one
- Model_Objects* anObjs = std::dynamic_pointer_cast<Model_Document>(theDoc)->objects();
- if (!anObjs) return;
- FeaturePtr aFeatureIter = anObjs->firstFeature();
- for (; aFeatureIter.get(); aFeatureIter = anObjs->nextFeature(aFeatureIter)) {
- if (aFeatureIter && alreadyProcessed.find(aFeatureIter) == alreadyProcessed.end()) {
- // update selection and parameters attributes first, before sub-features analysis (sketch plane)
- updateArguments(aFeatureIter);
- // composite feature must be executed after sub-features execution
- CompositeFeaturePtr aComposite =
- std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aFeatureIter);
- if (aComposite) {
- // number of subs can be changed in execution: like fillet
- for(int a = 0; a < aComposite->numberOfSubs(); a++) {
- FeaturePtr aSub = aComposite->subFeature(a);
- updateFeature(aSub);
- alreadyProcessed.insert(aSub);
- }
+ // check all features this feature depended on (recursive call of updateFeature)
+ static ModelAPI_ValidatorsFactory* aFactory = ModelAPI_Session::get()->validators();
+
+ if (theFeature->isDisabled())
+ return;
+
+ #ifdef DEB_UPDATE
+ std::cout<<"Update Feature "<<theFeature->name()<<std::endl;
+ #endif
+ 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() || 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);
+ ModelAPI_EventCreator::get()->sendUpdated(theFeature, EVENT_DISP);
+ return;
+ }
+
+ // Update selection and parameters attributes first, before sub-features analysis (sketch plane).
+ updateArguments(theFeature);
+
+ // composite feature must be executed after sub-features execution
+ if (aCompos) {
+ if (!iterateUpdate(aCompos))
+ return; // iteration was interrupted, so, interrupt the update of this feature (it will be done later)
+ // reupdate arguments of composite feature: it may be changed during subs execution
+
+ // issue 955: extrusion fuse sketch naming must be updated after the sketch update
+ // so, comment this: if (theFeature->data()->execState() != ModelAPI_StateMustBeUpdated)
+ updateArguments(theFeature);
+ }
+ // this checking must be after the composite feature sub-elements processing:
+ // composite feature status may depend on it's subelements
+ if (theFeature->data()->execState() == ModelAPI_StateInvalidArgument) {
+ theFeature->eraseResults();
+ redisplayWithResults(theFeature, ModelAPI_StateInvalidArgument); // result also must be updated
+ 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;
+
+ // On abort, undo or redo execute is not needed: results in document are updated automatically
+ // But redisplay is needed: results are updated, must be also updated in the viewer.
+ if (aJustUpdated &&
+ !std::dynamic_pointer_cast<Model_Document>(theFeature->document())->executeFeatures()) {
+ if (!theFeature->isPersistentResult()) { // not persistent must be re-executed on abort, etc.
+ ModelAPI_ExecState aState = theFeature->data()->execState();
+ if (aFactory->validate(theFeature)) {
+ executeFeature(theFeature);
+ } else {
+ theFeature->eraseResults();
+ redisplayWithResults(theFeature, ModelAPI_StateInvalidArgument); // result also must be updated