#include <Model_ResultBody.h>
#include <Model_ResultCompSolid.h>
#include <Model_ResultGroup.h>
+#include <Model_ResultField.h>
#include <Model_ResultParameter.h>
#include <ModelAPI_Validator.h>
#include <ModelAPI_CompositeFeature.h>
myDoc = theDoc;
// update all fields and recreate features and result objects if needed
TDF_LabelList aNoUpdated;
- synchronizeFeatures(aNoUpdated, true, true, true);
+ synchronizeFeatures(aNoUpdated, true, true, true, true);
myHistory.clear();
}
ModelAPI_EventCreator::get()->sendDeleted(myDoc, ModelAPI_Feature::group());
ModelAPI_EventCreator::get()->sendUpdated(aFeature, EVENT_DISP);
aFeature->removeResults(0, false);
- //aFeature->eraseResults();
aFeature->erase();
myFeatures.UnBind(aFeaturesIter.Key());
}
}
}
+void Model_Objects::eraseAllFeatures()
+{
+ static Events_ID kDispEvent = Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY);
+ static const ModelAPI_EventCreator* kCreator = ModelAPI_EventCreator::get();
+ // make all features invalid (like deleted)
+ NCollection_DataMap<TDF_Label, FeaturePtr>::Iterator aFIter(myFeatures);
+ for(; aFIter.More(); aFIter.Next()) {
+ FeaturePtr aFeature = aFIter.Value();
+ std::list<ResultPtr> aResList;
+ ModelAPI_Tools::allResults(aFeature, aResList);
+ std::list<ResultPtr>::iterator aRIter = aResList.begin();
+ for(; aRIter != aResList.end(); aRIter++) {
+ ResultPtr aRes = *aRIter;
+ if (aRes && aRes->data()->isValid()) {
+ kCreator->sendDeleted(myDoc, aRes->groupName());
+ kCreator->sendUpdated(aRes, kDispEvent);
+ aRes->setData(aRes->data()->invalidPtr());
+
+ }
+ }
+ kCreator->sendUpdated(aFeature, kDispEvent);
+ aFeature->setData(aFeature->data()->invalidPtr());
+ }
+ kCreator->sendDeleted(myDoc, ModelAPI_Feature::group());
+ myFeatures.Clear(); // just remove features without modification of DS
+ updateHistory(ModelAPI_Feature::group());
+}
+
void Model_Objects::moveFeature(FeaturePtr theMoved, FeaturePtr theAfterThis)
{
TDF_Label aFeaturesLab = featuresLabel();
void Model_Objects::synchronizeFeatures(
const TDF_LabelList& theUpdated, const bool theUpdateReferences,
- const bool theOpen, const bool theFlush)
+ const bool theExecuteFeatures, const bool theOpen, const bool theFlush)
{
Model_Document* anOwner = std::dynamic_pointer_cast<Model_Document>(myDoc).get();
if (!anOwner) // this may happen on creation of document: nothing there, so nothing to synchronize
aFeature = myFeatures.Find(aFeatureLabel);
aKeptFeatures.insert(aFeature);
if (anUpdatedMap.Contains(aFeatureLabel)) {
- if (!theOpen) { // on abort/undo/redo reinitialize attributes is something is changed
+ if (!theOpen) { // on abort/undo/redo reinitialize attributes if something is changed
std::list<std::shared_ptr<ModelAPI_Attribute> > anAttrs =
aFeature->data()->attributes("");
std::list<std::shared_ptr<ModelAPI_Attribute> >::iterator anAttr = anAttrs.begin();
// they may be connected, like sketch and sub elements)
// After synchronisation of back references because sketch
// must be set in sub-elements before "execute" by updateResults
- std::list<FeaturePtr> aComposites; // composites must be updated after their subs (issue 360)
+ std::set<FeaturePtr> aProcessed; // composites must be updated after their subs (issue 360)
TDF_ChildIDIterator aLabIter2(featuresLabel(), TDataStd_Comment::GetID());
for (; aLabIter2.More(); aLabIter2.Next()) {
TDF_Label aFeatureLabel = aLabIter2.Value()->Label();
if (myFeatures.IsBound(aFeatureLabel)) { // a new feature is inserted
FeaturePtr aFeature = myFeatures.Find(aFeatureLabel);
- if (std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aFeature).get())
- aComposites.push_back(aFeature);
- else
- updateResults(aFeature);
+ updateResults(aFeature, aProcessed);
}
}
- std::list<FeaturePtr>::iterator aComposite = aComposites.begin();
- for(; aComposite != aComposites.end(); aComposite++) {
- updateResults(*aComposite);
- }
-
// the synchronize should be done after updateResults
// in order to correct back references of updated results
if (theUpdateReferences) {
myHistory.clear();
}
- if (theOpen)
+ if (theExecuteFeatures)
anOwner->executeFeatures() = false;
aLoop->activateFlushes(isActive);
aLoop->flush(aRedispEvent);
aLoop->flush(aToHideEvent);
}
- if (theOpen)
+ if (theExecuteFeatures)
anOwner->executeFeatures() = true;
}
return aResult;
}
+std::shared_ptr<ModelAPI_ResultField> Model_Objects::createField(
+ const std::shared_ptr<ModelAPI_Data>& theFeatureData, const int theIndex)
+{
+ TDF_Label aLab = resultLabel(theFeatureData, theIndex);
+ TDataStd_Comment::Set(aLab, ModelAPI_ResultField::group().c_str());
+ ObjectPtr anOldObject = object(aLab);
+ std::shared_ptr<ModelAPI_ResultField> aResult;
+ if (anOldObject.get()) {
+ aResult = std::dynamic_pointer_cast<ModelAPI_ResultField>(anOldObject);
+ }
+ if (!aResult.get()) {
+ aResult = std::shared_ptr<ModelAPI_ResultField>(new Model_ResultField(theFeatureData));
+ storeResult(theFeatureData, aResult, theIndex);
+ }
+ return aResult;
+}
+
std::shared_ptr<ModelAPI_ResultParameter> Model_Objects::createParameter(
const std::shared_ptr<ModelAPI_Data>& theFeatureData, const int theIndex)
{
return anEmpty; // not found
}
-void Model_Objects::updateResults(FeaturePtr theFeature)
+void Model_Objects::updateResults(FeaturePtr theFeature, std::set<FeaturePtr>& theProcessed)
{
+ if (theProcessed.find(theFeature) != theProcessed.end())
+ return;
+ theProcessed.insert(theFeature);
+ // for composites update subs recursively (sketch elements results are needed for the sketch)
+ CompositeFeaturePtr aComp = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(theFeature);
+ if (aComp.get() && aComp->getKind() != "Part") { // don't go inside of parts sub-features
+ // update subs of composites first
+ int aSubNum = aComp->numberOfSubs();
+ for(int a = 0; a < aSubNum; a++) {
+ FeaturePtr aSub = aComp->subFeature(a);
+ updateResults(aComp->subFeature(a), theProcessed);
+ }
+ }
+
// for not persistent is will be done by parametric updater automatically
//if (!theFeature->isPersistentResult()) return;
// check the existing results and remove them if there is nothing on the label
if (!aNewP->partDoc().get())
// create the part result: it is better to restore the previous result if it is possible
theFeature->execute();
- break;
} else if (aGroup->Get() == ModelAPI_ResultConstruction::group().c_str()) {
theFeature->execute(); // construction shapes are needed for sketch solver
- break;
} else if (aGroup->Get() == ModelAPI_ResultGroup::group().c_str()) {
aNewBody = createGroup(theFeature->data(), aResIndex);
+ } else if (aGroup->Get() == ModelAPI_ResultField::group().c_str()) {
+ aNewBody = createField(theFeature->data(), aResIndex);
} else if (aGroup->Get() == ModelAPI_ResultParameter::group().c_str()) {
theFeature->attributeChanged("expression"); // just produce a value
- break;
} else {
Events_InfoMessage("Model_Objects", "Unknown type of result is found in the document:")
.arg(TCollection_AsciiString(aGroup->Get()).ToCString()).send();