X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSketchSolver%2FSketchSolver_Manager.cpp;h=8e976d02b9dd8d370fc3f515ddd47be4e2c30900;hb=334029ee7a94867a1ed39d7ba51b6e49770b6e34;hp=ec2f8d77bbb5be2f5047486ca7579ed016315d14;hpb=7244aa3984b1d326f2c79e004b6d29de13ba1667;p=modules%2Fshaper.git diff --git a/src/SketchSolver/SketchSolver_Manager.cpp b/src/SketchSolver/SketchSolver_Manager.cpp index ec2f8d77b..8e976d02b 100644 --- a/src/SketchSolver/SketchSolver_Manager.cpp +++ b/src/SketchSolver/SketchSolver_Manager.cpp @@ -1,13 +1,28 @@ -// Copyright (C) 2014-20xx CEA/DEN, EDF R&D - -// File: SketchSolver_Manager.cpp -// Created: 08 May 2014 -// Author: Artem ZHIDKOV +// Copyright (C) 2014-2017 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or +// email : webmaster.salome@opencascade.com +// #include "SketchSolver_Manager.h" #include "SketchSolver_Error.h" #include +#include #include #include #include @@ -78,6 +93,7 @@ void SketchSolver_Manager::processEvent( bool isUpdateFlushed = false; bool isMovedEvt = false; + static const Events_ID aCreatedEvent = Events_Loop::eventByName(EVENT_OBJECT_CREATED); static const Events_ID anUpdateEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED); static const Events_ID aSketchPreparedEvent = Events_Loop::eventByName(EVENT_SKETCH_PREPARED); // sketch is prepared for resolve: all the needed events @@ -91,46 +107,71 @@ void SketchSolver_Manager::processEvent( return; myIsComputed = true; - if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_CREATED) - || theMessage->eventID() == anUpdateEvent - || theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_MOVED)) { + if (theMessage->eventID() == aCreatedEvent || theMessage->eventID() == anUpdateEvent) { std::shared_ptr anUpdateMsg = std::dynamic_pointer_cast(theMessage); - std::set aFeatures = anUpdateMsg->objects(); isUpdateFlushed = stopSendUpdate(); - isMovedEvt = theMessage->eventID() - == Events_Loop::loop()->eventByName(EVENT_OBJECT_MOVED); - - // Shows that the message has at least one feature applicable for solver - bool hasProperFeature = false; - // update sketch features only - std::set::iterator aFeatIter; - for (aFeatIter = aFeatures.begin(); aFeatIter != aFeatures.end(); aFeatIter++) { - std::shared_ptr aFeature = - std::dynamic_pointer_cast(*aFeatIter); - if (!aFeature || aFeature->isMacro()) - continue; - - hasProperFeature = updateFeature(aFeature, isMovedEvt) || hasProperFeature; + const std::set& aFeatures = anUpdateMsg->objects(); + // try to keep order as features were created if there are several created features: #2229 + if (theMessage->eventID() == aCreatedEvent && aFeatures.size() > 1) { + std::map> anOrderedFeatures; + std::set::iterator aFeatIter; + for (aFeatIter = aFeatures.begin(); aFeatIter != aFeatures.end(); aFeatIter++) { + std::shared_ptr aFeature = + std::dynamic_pointer_cast(*aFeatIter); + if (aFeature && !aFeature->isMacro() && aFeature->data() && aFeature->data()->isValid()) { + anOrderedFeatures[aFeature->data()->featureId()] = aFeature; + } + } + std::map>::iterator aFeat; + for(aFeat = anOrderedFeatures.begin(); aFeat != anOrderedFeatures.end(); aFeat++) { + updateFeature(aFeat->second); + } + } else { // order is not important + std::set::iterator aFeatIter; + for (aFeatIter = aFeatures.begin(); aFeatIter != aFeatures.end(); aFeatIter++) { + std::shared_ptr aFeature = + std::dynamic_pointer_cast(*aFeatIter); + if (aFeature && !aFeature->isMacro()) + updateFeature(aFeature); + } } - if (isMovedEvt && hasProperFeature) - needToResolve = true; + } else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_MOVED)) { + std::shared_ptr aMoveMsg = + std::dynamic_pointer_cast(theMessage); + + ObjectPtr aMovedObject = aMoveMsg->movedObject(); + std::shared_ptr aMovedPoint = + std::dynamic_pointer_cast(aMoveMsg->movedAttribute()); + + const std::shared_ptr& aFrom = aMoveMsg->originalPosition(); + const std::shared_ptr& aTo = aMoveMsg->currentPosition(); + + if (aMovedObject) { + FeaturePtr aMovedFeature = ModelAPI_Feature::feature(aMovedObject); + std::shared_ptr aSketchFeature = + std::dynamic_pointer_cast(aMovedFeature); + if (aSketchFeature && !aSketchFeature->isMacro()) + needToResolve = moveFeature(aSketchFeature, aFrom, aTo); + } else if (aMovedPoint) + needToResolve = moveAttribute(aMovedPoint, aFrom, aTo); } else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_DELETED)) { std::shared_ptr aDeleteMsg = std::dynamic_pointer_cast(theMessage); - const std::set& aFeatureGroups = aDeleteMsg->groups(); + const std::list, std::string>>& aFeatureGroups = + aDeleteMsg->groups(); // Find SketchPlugin_Sketch::ID() in groups. // The constraint groups should be updated when an object removed from Sketch - std::set::const_iterator aFGrIter; + std::list, std::string>>::const_iterator aFGrIter; for (aFGrIter = aFeatureGroups.begin(); aFGrIter != aFeatureGroups.end(); aFGrIter++) - if (aFGrIter->compare(ModelAPI_ResultConstruction::group()) == 0 || - aFGrIter->compare(ModelAPI_Feature::group()) == 0) + if (aFGrIter->second == ModelAPI_ResultConstruction::group() || + aFGrIter->second == ModelAPI_Feature::group()) break; if (aFGrIter != aFeatureGroups.end()) { @@ -151,6 +192,7 @@ void SketchSolver_Manager::processEvent( // resolve constraints if needed bool needToUpdate = needToResolve && resolveConstraints(); + releaseFeaturesIfEventsBlocked(); // Features may be updated => now send events, but for all changed at once if (isUpdateFlushed) @@ -164,11 +206,10 @@ void SketchSolver_Manager::processEvent( } // ============================================================================ -// Function: changeConstraintOrEntity -// Purpose: create/update the constraint or the feature and place it into appropriate group +// Function: updateFeature +// Purpose: create/update constraint or feature in appropriate group // ============================================================================ -bool SketchSolver_Manager::updateFeature(std::shared_ptr theFeature, - bool theMoved) +bool SketchSolver_Manager::updateFeature(const std::shared_ptr& theFeature) { // Check feature validity and find a group to place it. // If the feature is not valid, the returned group will be empty. @@ -184,13 +225,75 @@ bool SketchSolver_Manager::updateFeature(std::shared_ptr t bool isOk = false; if (aConstraint) isOk = aGroup->changeConstraint(aConstraint); - else if (theMoved) - isOk = aGroup->moveFeature(theFeature); else isOk = aGroup->updateFeature(theFeature); return isOk; } +// ============================================================================ +// Function: moveFeature +// Purpose: move given feature in appropriate group +// ============================================================================ +bool SketchSolver_Manager::moveFeature( + const std::shared_ptr& theMovedFeature, + const std::shared_ptr& theFrom, + const std::shared_ptr& theTo) +{ + SketchGroupPtr aGroup = findGroup(theMovedFeature); + if (!aGroup) + return false; + + std::shared_ptr aConstraint = + std::dynamic_pointer_cast(theMovedFeature); + if (aConstraint) + { + std::shared_ptr aPntAttr = std::dynamic_pointer_cast + (aConstraint->attribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT())); + if (aPntAttr) + { + aPntAttr->setValue(theTo); + Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED)); + } + return true; + } + + aGroup->blockEvents(true); + return aGroup->moveFeature(theMovedFeature, theFrom, theTo); +} + +// ============================================================================ +// Function: moveAttribute +// Purpose: move given attribute in appropriate group +// ============================================================================ +bool SketchSolver_Manager::moveAttribute( + const std::shared_ptr& theMovedAttribute, + const std::shared_ptr& theFrom, + const std::shared_ptr& theTo) +{ + FeaturePtr anOwner = ModelAPI_Feature::feature(theMovedAttribute->owner()); + std::shared_ptr aConstraint = + std::dynamic_pointer_cast(anOwner); + if (aConstraint) + { + theMovedAttribute->setValue(theTo); + Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED)); + return true; + } + + std::shared_ptr aSketchFeature = + std::dynamic_pointer_cast(anOwner); + SketchGroupPtr aGroup; + if (aSketchFeature) + aGroup = findGroup(aSketchFeature); + if (!aGroup) { + theMovedAttribute->setValue(theTo); + return false; + } + + aGroup->blockEvents(true); + return aGroup->movePoint(theMovedAttribute, theFrom, theTo); +} + // ============================================================================ // Function: findGroup // Purpose: search groups of entities interacting with given feature @@ -238,11 +341,17 @@ bool SketchSolver_Manager::resolveConstraints() for (; aGroupIter != myGroups.end(); ++aGroupIter) { if ((*aGroupIter)->resolveConstraints()) needToUpdate = true; - (*aGroupIter)->blockEvents(false); } return needToUpdate; } +void SketchSolver_Manager::releaseFeaturesIfEventsBlocked() const +{ + std::list::const_iterator aGroupIter = myGroups.begin(); + for (; aGroupIter != myGroups.end(); ++aGroupIter) + (*aGroupIter)->blockEvents(false); +} + bool SketchSolver_Manager::stopSendUpdate() const { static const Events_ID anUpdateEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED);