X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FModel%2FModel_Objects.cpp;h=1361a931a49baca81ba39b0b83ee3ac10d237a62;hb=5183e45dbb598541fb76e679b285b1e599916eaa;hp=e87508864abad949886e2070b4001a5f18c5b833;hpb=d7d6265cce5e49374130cb4c6a4cfb3a90eba875;p=modules%2Fshaper.git diff --git a/src/Model/Model_Objects.cpp b/src/Model/Model_Objects.cpp index e87508864..1361a931a 100644 --- a/src/Model/Model_Objects.cpp +++ b/src/Model/Model_Objects.cpp @@ -105,11 +105,8 @@ void Model_Objects::addFeature(FeaturePtr theFeature, const FeaturePtr theAfterT if (!theFeature->isAction()) { // do not add action to the data model TDF_Label aFeaturesLab = featuresLabel(); TDF_Label aFeatureLab = aFeaturesLab.NewChild(); - initData(theFeature, aFeatureLab, TAG_FEATURE_ARGUMENTS); - // keep the feature ID to restore document later correctly - TDataStd_Comment::Set(aFeatureLab, theFeature->getKind().c_str()); - myFeatures.Bind(aFeatureLab, theFeature); - // store feature in the features array + // store feature in the features array: before "initData" because in macro features + // in initData it creates new features, appeared later than this TDF_Label aPrevFeateureLab; if (theAfterThis.get()) { // searching for the previous feature label std::shared_ptr aPrevData = @@ -119,11 +116,19 @@ void Model_Objects::addFeature(FeaturePtr theFeature, const FeaturePtr theAfterT } } AddToRefArray(aFeaturesLab, aFeatureLab, aPrevFeateureLab); + + initData(theFeature, aFeatureLab, TAG_FEATURE_ARGUMENTS); + // keep the feature ID to restore document later correctly + TDataStd_Comment::Set(aFeatureLab, theFeature->getKind().c_str()); + myFeatures.Bind(aFeatureLab, theFeature); // event: feature is added static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_CREATED); ModelAPI_EventCreator::get()->sendUpdated(theFeature, anEvent); theFeature->setDisabled(false); // by default created feature is enabled updateHistory(ModelAPI_Feature::group()); + } else { // make feature has not-null data anyway + theFeature->setData(Model_Data::invalidData()); + theFeature->setDoc(myDoc); } } @@ -201,14 +206,7 @@ void Model_Objects::refsToFeature(FeaturePtr theFeature, void Model_Objects::removeFeature(FeaturePtr theFeature) { std::shared_ptr aData = std::static_pointer_cast(theFeature->data()); - if (aData) { - TDF_Label aFeatureLabel = aData->label().Father(); - if (myFeatures.IsBound(aFeatureLabel)) - myFeatures.UnBind(aFeatureLabel); - else - return; // not found feature => do not remove - - clearHistory(theFeature); + if (aData && aData->isValid()) { // checking that the sub-element of composite feature is removed: if yes, inform the owner std::set > aRefs; refsToFeature(theFeature, aRefs, false); @@ -220,16 +218,23 @@ void Model_Objects::removeFeature(FeaturePtr theFeature) aComposite->removeFeature(theFeature); } } + // this must be before erase since theFeature erasing removes all information about + // the feature results and groups of results + // To reproduce: create sketch, extrusion, remove sketch => constructions tree is not updated + clearHistory(theFeature); // erase fields theFeature->erase(); + + TDF_Label aFeatureLabel = aData->label().Father(); + if (myFeatures.IsBound(aFeatureLabel)) + myFeatures.UnBind(aFeatureLabel); + static Events_ID EVENT_DISP = Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY); ModelAPI_EventCreator::get()->sendUpdated(theFeature, EVENT_DISP); // erase all attributes under the label of feature aFeatureLabel.ForgetAllAttributes(); // remove it from the references array - if (theFeature->isInHistory()) { - RemoveFromRefArray(featuresLabel(), aFeatureLabel); - } + RemoveFromRefArray(featuresLabel(), aFeatureLabel); // event: feature is deleted ModelAPI_EventCreator::get()->sendDeleted(theFeature->document(), ModelAPI_Feature::group()); // the redisplay signal should be flushed in order to erase the feature presentation in the viewer @@ -247,8 +252,13 @@ void Model_Objects::clearHistory(ObjectPtr theObj) myHistory.erase(aHIter); // erase from map => this means that it is not synchronized if (theObj->groupName() == ModelAPI_Feature::group()) { // clear results group of the feature FeaturePtr aFeature = std::dynamic_pointer_cast(theObj); - if (aFeature->firstResult().get()) - clearHistory(aFeature->firstResult()); + std::string aResultGroup = featureResultGroup(aFeature); + if (!aResultGroup.empty()) { + std::map >::iterator aHIter = + myHistory.find(aResultGroup); + if (aHIter != myHistory.end()) + myHistory.erase(aHIter); // erase from map => this means that it is not synchronized + } } } } @@ -329,6 +339,8 @@ ObjectPtr Model_Objects::object(TDF_Label theLabel) ObjectPtr Model_Objects::object(const std::string& theGroupID, const int theIndex) { + if (theIndex == -1) + return ObjectPtr(); createHistory(theGroupID); return myHistory[theGroupID][theIndex]; } @@ -463,7 +475,7 @@ void Model_Objects::synchronizeFeatures( static Events_ID aRedispEvent = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY); static Events_ID aDeleteEvent = Events_Loop::eventByName(EVENT_OBJECT_DELETED); static Events_ID aToHideEvent = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY); - aLoop->activateFlushes(false); + bool isActive = aLoop->activateFlushes(false); // update all objects by checking are they on labels or not std::set aNewFeatures, aKeptFeatures; @@ -486,6 +498,7 @@ void Model_Objects::synchronizeFeatures( aNewFeatures.insert(aFeature); initData(aFeature, aFeatureLabel, TAG_FEATURE_ARGUMENTS); updateHistory(aFeature); + aFeature->setDisabled(false); // by default created feature is enabled (this allows to recreate the results before "setCurrent" is called) // event: model is updated ModelAPI_EventCreator::get()->sendUpdated(aFeature, aCreateEvent); @@ -545,7 +558,7 @@ void Model_Objects::synchronizeFeatures( } anOwner->executeFeatures() = false; - aLoop->activateFlushes(true); + aLoop->activateFlushes(isActive); if (theFlush) { aLoop->flush(aCreateEvent); @@ -600,6 +613,15 @@ void Model_Objects::synchronizeBackRefs() std::shared_ptr aRefData = std::dynamic_pointer_cast((*aRefTo)->data()); aRefData->addBackReference(aFeature, aRefsIter->first); // here the Concealed flag is updated + // update enable/disable status: the nested status must be equal to the composite + CompositeFeaturePtr aComp = + std::dynamic_pointer_cast(aFeature); + if (aComp.get()) { + FeaturePtr aReferenced = std::dynamic_pointer_cast(*aRefTo); + if (aReferenced.get()) { + aReferenced->setDisabled(aComp->isDisabled()); + } + } } } } @@ -741,6 +763,22 @@ std::shared_ptr Model_Objects::feature( return FeaturePtr(); } +std::string Model_Objects::featureResultGroup(FeaturePtr theFeature) +{ + if (theFeature->data()->isValid()) { + TDF_ChildIterator aLabIter(resultLabel(theFeature->data(), 0).Father()); + if (aLabIter.More()) { + TDF_Label anArgLab = aLabIter.Value(); + Handle(TDataStd_Comment) aGroup; + if (aLabIter.Value().FindAttribute(TDataStd_Comment::GetID(), aGroup)) { + return TCollection_AsciiString(aGroup->Get()).ToCString(); + } + } + } + static std::string anEmpty; + return anEmpty; // not found +} + void Model_Objects::updateResults(FeaturePtr theFeature) { // for not persistent is will be done by parametric updater automatically @@ -749,10 +787,10 @@ void Model_Objects::updateResults(FeaturePtr theFeature) std::list::const_iterator aResIter = theFeature->results().cbegin(); while(aResIter != theFeature->results().cend()) { ResultPtr aBody = std::dynamic_pointer_cast(*aResIter); - if (aBody) { + if (aBody.get()) { if (!aBody->data()->isValid()) { // found a disappeared result => remove it - theFeature->removeResult(aBody); + theFeature->eraseResultFromList(aBody); // start iterate from beginning because iterator is corrupted by removing aResIter = theFeature->results().cbegin(); continue; @@ -777,7 +815,11 @@ void Model_Objects::updateResults(FeaturePtr theFeature) if (aGroup->Get() == ModelAPI_ResultBody::group().c_str()) { aNewBody = createBody(theFeature->data(), aResIndex); } else if (aGroup->Get() == ModelAPI_ResultPart::group().c_str()) { - aNewBody = createPart(theFeature->data(), aResIndex); + std::shared_ptr aNewP = createPart(theFeature->data(), aResIndex); + theFeature->setResult(aNewP, aResIndex); + if (!aNewP->partDoc().get()) + theFeature->execute(); // create the part result: it is better to restore the previous result if it is possible + break; } else if (aGroup->Get() == ModelAPI_ResultConstruction::group().c_str()) { theFeature->execute(); // construction shapes are needed for sketch solver break; @@ -822,7 +864,7 @@ ResultPtr Model_Objects::findByName(const std::string theName) FeaturePtr Model_Objects::nextFeature(FeaturePtr theCurrent, const bool theReverse) { std::shared_ptr aData = std::static_pointer_cast(theCurrent->data()); - if (aData) { + if (aData && aData->isValid()) { TDF_Label aFeatureLabel = aData->label().Father(); Handle(TDataStd_ReferenceArray) aRefs; if (featuresLabel().FindAttribute(TDataStd_ReferenceArray::GetID(), aRefs)) { @@ -857,6 +899,20 @@ FeaturePtr Model_Objects::lastFeature() return FeaturePtr(); // no features at all } +std::list > Model_Objects::allFeatures() +{ + std::list > aResult; + Handle(TDataStd_ReferenceArray) aRefs; + if (featuresLabel().FindAttribute(TDataStd_ReferenceArray::GetID(), aRefs)) { + for(int a = aRefs->Lower(); a <= aRefs->Upper(); a++) { + FeaturePtr aFeature = feature(aRefs->Value(a)); + if (aFeature.get()) + aResult.push_back(aFeature); + } + } + return aResult; +} + Standard_Integer HashCode(const TDF_Label& theLab, const Standard_Integer theUpper) { return TDF_LabelMapHasher::HashCode(theLab, theUpper);