From 88eab57964bc44393dcabf4ccbf8316f3b23fdac Mon Sep 17 00:00:00 2001 From: mpv Date: Fri, 7 Nov 2014 09:38:16 +0300 Subject: [PATCH] The parametric update of loaded documents: sketch solver problems fix --- src/Model/Model_Document.cpp | 24 +++++++++++++------ src/Model/Model_Update.cpp | 8 ++++++- src/SketchPlugin/SketchPlugin_Circle.cpp | 3 ++- src/SketchPlugin/SketchPlugin_Line.cpp | 2 +- src/SketchPlugin/SketchPlugin_Sketch.cpp | 2 ++ .../SketchSolver_ConstraintManager.cpp | 23 +++++++++--------- 6 files changed, 41 insertions(+), 21 deletions(-) diff --git a/src/Model/Model_Document.cpp b/src/Model/Model_Document.cpp index 8bb7c7809..15983188d 100644 --- a/src/Model/Model_Document.cpp +++ b/src/Model/Model_Document.cpp @@ -737,9 +737,6 @@ void Model_Document::synchronizeFeatures(const bool theMarkUpdated, const bool t // event: model is updated static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_CREATED); ModelAPI_EventCreator::get()->sendUpdated(aFeature, anEvent); - - // update results of the appeared feature - updateResults(aFeature); } else { // nothing is changed, both iterators are incremented aFeature = myObjs.Find(aFeatureLabel); aKeptFeatures.insert(aFeature); @@ -747,9 +744,18 @@ void Model_Document::synchronizeFeatures(const bool theMarkUpdated, const bool t static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED); ModelAPI_EventCreator::get()->sendUpdated(aFeature, anEvent); } + } + } + // update results of thefeatures (after features created because they may be connected, like sketch and sub elements) + TDF_ChildIDIterator aLabIter2(featuresLabel(), TDataStd_Comment::GetID()); + for (; aLabIter2.More(); aLabIter2.Next()) { + TDF_Label aFeatureLabel = aLabIter2.Value()->Label(); + if (myObjs.IsBound(aFeatureLabel)) { // a new feature is inserted + FeaturePtr aFeature = myObjs.Find(aFeatureLabel); updateResults(aFeature); } } + // check all features are checked: if not => it was removed NCollection_DataMap::Iterator aFIter(myObjs); while (aFIter.More()) { @@ -957,11 +963,11 @@ boost::shared_ptr Model_Document::feature( void Model_Document::updateResults(FeaturePtr theFeature) { // for not persistent is will be done by parametric updater automatically - if (!theFeature->isPersistentResult()) return; + //if (!theFeature->isPersistentResult()) return; // check the existing results and remove them if there is nothing on the label std::list::const_iterator aResIter = theFeature->results().cbegin(); while(aResIter != theFeature->results().cend()) { - ResultBodyPtr aBody = boost::dynamic_pointer_cast(*aResIter); + ResultPtr aBody = boost::dynamic_pointer_cast(*aResIter); if (aBody) { if (!aBody->data()->isValid()) { // found a disappeared result => remove it @@ -988,8 +994,12 @@ void Model_Document::updateResults(FeaturePtr theFeature) aNewBody = createBody(theFeature->data(), aResIndex); } else if (aGroup->Get() == ModelAPI_ResultPart::group().c_str()) { aNewBody = createPart(theFeature->data(), aResIndex); - } else if (aGroup->Get() != ModelAPI_ResultConstruction::group().c_str() && - aGroup->Get() != ModelAPI_ResultGroup::group().c_str()) { + } 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 { Events_Error::send(std::string("Unknown type of result is found in the document:") + TCollection_AsciiString(aGroup->Get()).ToCString()); } diff --git a/src/Model/Model_Update.cpp b/src/Model/Model_Update.cpp index b6a4a9553..676e3ba2c 100644 --- a/src/Model/Model_Update.cpp +++ b/src/Model/Model_Update.cpp @@ -38,6 +38,8 @@ Model_Update::Model_Update() aLoop->registerListener(this, kCreatedEvent); static const Events_ID kUpdatedEvent = Events_Loop::loop()->eventByName(EVENT_OBJECT_UPDATED); aLoop->registerListener(this, kUpdatedEvent); + static const Events_ID kMovedEvent = Events_Loop::loop()->eventByName(EVENT_OBJECT_MOVED); + aLoop->registerListener(this, kMovedEvent); static const Events_ID kOpFinishEvent = aLoop->eventByName("FinishOperation"); aLoop->registerListener(this, kOpFinishEvent); static const Events_ID kOpAbortEvent = aLoop->eventByName("AbortOperation"); @@ -57,6 +59,7 @@ void Model_Update::processEvent(const boost::shared_ptr& theMess static const Events_ID kRebuildEvent = aLoop->eventByName("Rebuild"); static const Events_ID kCreatedEvent = aLoop->eventByName(EVENT_OBJECT_CREATED); static const Events_ID kUpdatedEvent = aLoop->eventByName(EVENT_OBJECT_UPDATED); + static const Events_ID kMovedEvent = Events_Loop::loop()->eventByName(EVENT_OBJECT_MOVED); static const Events_ID kOpFinishEvent = aLoop->eventByName("FinishOperation"); static const Events_ID kOpAbortEvent = aLoop->eventByName("AbortOperation"); static const Events_ID kOpStartEvent = aLoop->eventByName("StartOperation"); @@ -69,7 +72,8 @@ void Model_Update::processEvent(const boost::shared_ptr& theMess isAutomaticChanged = true; isAutomatic = true; } - } else if (theMessage->eventID() == kCreatedEvent || theMessage->eventID() == kUpdatedEvent) { + } else if (theMessage->eventID() == kCreatedEvent || theMessage->eventID() == kUpdatedEvent || + theMessage->eventID() == kMovedEvent) { boost::shared_ptr aMsg = boost::dynamic_pointer_cast(theMessage); const std::set& anObjs = aMsg->objects(); @@ -77,6 +81,8 @@ void Model_Update::processEvent(const boost::shared_ptr& theMess for(; anObjIter != anObjs.cend(); anObjIter++) { myJustCreatedOrUpdated.insert(*anObjIter); } + if (theMessage->eventID() == kMovedEvent) + return; // this event is for solver update, not here } else if (theMessage->eventID() == kOpStartEvent) { myJustCreatedOrUpdated.clear(); return; // we don't need the update only on operation start (caused problems in PartSet_Listener::processEvent) diff --git a/src/SketchPlugin/SketchPlugin_Circle.cpp b/src/SketchPlugin/SketchPlugin_Circle.cpp index 06ab76d14..3669232cb 100644 --- a/src/SketchPlugin/SketchPlugin_Circle.cpp +++ b/src/SketchPlugin/SketchPlugin_Circle.cpp @@ -102,7 +102,8 @@ bool SketchPlugin_Circle::isFixed() { void SketchPlugin_Circle::attributeChanged() { static bool myIsUpdated = false; // to avoid infinitive cycle on attrubtes change boost::shared_ptr aSelection = data()->selection(EXTERNAL_ID())->value(); - if (aSelection && !myIsUpdated) { // update arguments due to the selection value + // update arguments due to the selection value + if (aSelection && !aSelection->isNull() && aSelection->isEdge() && !myIsUpdated) { myIsUpdated = true; boost::shared_ptr anEdge( new GeomAPI_Edge(aSelection)); boost::shared_ptr aCirc = anEdge->circle(); diff --git a/src/SketchPlugin/SketchPlugin_Line.cpp b/src/SketchPlugin/SketchPlugin_Line.cpp index 95b6de896..22a466815 100644 --- a/src/SketchPlugin/SketchPlugin_Line.cpp +++ b/src/SketchPlugin/SketchPlugin_Line.cpp @@ -101,7 +101,7 @@ void SketchPlugin_Line::attributeChanged() { static bool myIsUpdated = false; // to avoid infinitive cycle on attrubtes change boost::shared_ptr aSelection = data()->selection(EXTERNAL_ID())->value(); // update arguments due to the selection value - if (aSelection && !aSelection->isNull() && !myIsUpdated) { + if (aSelection && !aSelection->isNull() && aSelection->isEdge() && !myIsUpdated) { myIsUpdated = true; boost::shared_ptr anEdge( new GeomAPI_Edge(aSelection)); boost::shared_ptr aStartAttr = diff --git a/src/SketchPlugin/SketchPlugin_Sketch.cpp b/src/SketchPlugin/SketchPlugin_Sketch.cpp index 2b45cb65a..813ce28fb 100644 --- a/src/SketchPlugin/SketchPlugin_Sketch.cpp +++ b/src/SketchPlugin/SketchPlugin_Sketch.cpp @@ -78,6 +78,8 @@ void SketchPlugin_Sketch::execute() for (; anIt != aLast; anIt++) { aFeature = boost::dynamic_pointer_cast(*anIt); if (aFeature) { + if (!aFeature->sketch()) // on load document the back references are missed + aFeature->setSketch(this); // do not include the external edges into the result if (aFeature->data()->attribute(SketchPlugin_Feature::EXTERNAL_ID())) { if (aFeature->data()->selection(SketchPlugin_Feature::EXTERNAL_ID())->value()) diff --git a/src/SketchSolver/SketchSolver_ConstraintManager.cpp b/src/SketchSolver/SketchSolver_ConstraintManager.cpp index 1dec2867f..d308e99d0 100644 --- a/src/SketchSolver/SketchSolver_ConstraintManager.cpp +++ b/src/SketchSolver/SketchSolver_ConstraintManager.cpp @@ -63,8 +63,8 @@ SketchSolver_ConstraintManager::~SketchSolver_ConstraintManager() void SketchSolver_ConstraintManager::processEvent( const boost::shared_ptr& theMessage) { - if (myIsComputed) - return; + //if (myIsComputed) + // return; if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_CREATED) || theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_UPDATED) || theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_MOVED)) { @@ -84,24 +84,25 @@ void SketchSolver_ConstraintManager::processEvent( } } else { std::set::iterator aFeatIter; + // iterate sketchers fisrt to create all sketches before (on load may exist several sketches) for (aFeatIter = aFeatures.begin(); aFeatIter != aFeatures.end(); aFeatIter++) { FeaturePtr aFeature = boost::dynamic_pointer_cast(*aFeatIter); if (!aFeature) continue; - // Only sketches and constraints can be added by Create event const std::string& aFeatureKind = aFeature->getKind(); if (aFeatureKind.compare(SketchPlugin_Sketch::ID()) == 0) { boost::shared_ptr aSketch = boost::dynamic_pointer_cast< ModelAPI_CompositeFeature>(aFeature); - if (aSketch) - changeWorkplane(aSketch); - continue; + changeWorkplane(aSketch); } - // Sketch plugin features can be only updated - boost::shared_ptr aSFeature = boost::dynamic_pointer_cast< - SketchPlugin_Feature>(aFeature); - if (aSFeature) - changeConstraintOrEntity(aSFeature); + } + // then get anything but not the sketch + for (aFeatIter = aFeatures.begin(); aFeatIter != aFeatures.end(); aFeatIter++) { + boost::shared_ptr aFeature = + boost::dynamic_pointer_cast(*aFeatIter); + if (!aFeature) + continue; + changeConstraintOrEntity(aFeature); } } -- 2.39.2