X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2FSketchSolver%2FSketchSolver_Manager.cpp;h=56b874f64f372c1485b9ff52b9734c5776b3a4a3;hb=a74fbd0025bc36fc76b5559d960857f419446ecb;hp=d253916c981ded6b8df351a2d92e0c8323a5000b;hpb=a94fc319f2aa64b43c9a73b5ff7063923648faec;p=modules%2Fshaper.git diff --git a/src/SketchSolver/SketchSolver_Manager.cpp b/src/SketchSolver/SketchSolver_Manager.cpp index d253916c9..56b874f64 100644 --- a/src/SketchSolver/SketchSolver_Manager.cpp +++ b/src/SketchSolver/SketchSolver_Manager.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 CEA/DEN, EDF R&D +// Copyright (C) 2014-2021 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 @@ -12,10 +12,9 @@ // // 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 +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or -// email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // #include "SketchSolver_Manager.h" @@ -23,11 +22,11 @@ #include #include +#include #include #include #include #include -#include #include /// Global constraint manager object @@ -44,6 +43,64 @@ static bool isFeatureValid(FeaturePtr theFeature) return aFactory->validate(theFeature); } +typedef std::map> IndexedFeatureMap; + +static void featuresOrderedByCreation(const std::set& theOriginalFeatures, + IndexedFeatureMap& theOrderedFeatures) +{ + std::set::iterator aFeatIter = theOriginalFeatures.begin(); + for (; aFeatIter != theOriginalFeatures.end(); aFeatIter++) { + std::shared_ptr aFeature = + std::dynamic_pointer_cast(*aFeatIter); + if (aFeature && !aFeature->isMacro() && aFeature->data() && aFeature->data()->isValid()) { + theOrderedFeatures[aFeature->data()->featureId()] = aFeature; + } + } +} + +static void featuresOrderedByType(const std::set& theOriginalFeatures, + IndexedFeatureMap& theOrderedFeatures, + CompositeFeaturePtr& theSketch) +{ + int aFeatureIndex = 0; + int aConstraintIndex = (int)theOriginalFeatures.size(); + + std::set::iterator aFeatIter = theOriginalFeatures.begin(); + for (; aFeatIter != theOriginalFeatures.end(); aFeatIter++) { + std::shared_ptr aFeature = + std::dynamic_pointer_cast(*aFeatIter); + if (aFeature) { + if (!aFeature->isMacro() && aFeature->data() && aFeature->data()->isValid()) { + std::shared_ptr aConstraint = + std::dynamic_pointer_cast(aFeature); + if (aConstraint) + theOrderedFeatures[++aConstraintIndex] = aFeature; + else + theOrderedFeatures[++aFeatureIndex] = aFeature; + } + } + else { + CompositeFeaturePtr aSketch = + std::dynamic_pointer_cast(*aFeatIter); + if (aSketch && aSketch->getKind() == SketchPlugin_Sketch::ID()) + theSketch = aSketch; + } + } +} + +static void setPoint(AttributePtr theAttribute, + const int thePointIndex, + const std::shared_ptr theValue) +{ + AttributePoint2DPtr aPointAttr = std::dynamic_pointer_cast(theAttribute); + AttributePoint2DArrayPtr aPointArrayAttr = + std::dynamic_pointer_cast(theAttribute); + if (aPointAttr) + aPointAttr->setValue(theValue); + else if (aPointArrayAttr && thePointIndex >= 0) + aPointArrayAttr->setPnt(thePointIndex, theValue); +} + // ======================================================== @@ -68,7 +125,10 @@ SketchSolver_Manager::SketchSolver_Manager() Events_Loop::loop()->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_DELETED)); Events_Loop::loop()->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_MOVED)); + ////Events_Loop::loop()->registerListener(this, Events_Loop::eventByName(EVENT_SOLVER_FAILED)); + ////Events_Loop::loop()->registerListener(this, Events_Loop::eventByName(EVENT_SOLVER_REPAIRED)); Events_Loop::loop()->registerListener(this, Events_Loop::eventByName(EVENT_SKETCH_PREPARED)); + Events_Loop::loop()->registerListener(this, Events_Loop::eventByName(EVENT_GET_DOF_OBJECTS)); } SketchSolver_Manager::~SketchSolver_Manager() @@ -92,6 +152,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 @@ -105,32 +166,36 @@ void SketchSolver_Manager::processEvent( return; myIsComputed = true; - if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_CREATED) - || theMessage->eventID() == anUpdateEvent) { + if (theMessage->eventID() == aCreatedEvent || theMessage->eventID() == anUpdateEvent) { std::shared_ptr anUpdateMsg = std::dynamic_pointer_cast(theMessage); - std::set aFeatures = anUpdateMsg->objects(); isUpdateFlushed = stopSendUpdate(); // 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; - - updateFeature(aFeature); + const std::set& aFeatures = anUpdateMsg->objects(); + IndexedFeatureMap anOrderedFeatures; + CompositeFeaturePtr aSketchFeature; + // try to keep order as features were created if there are several created features: #2229 + if (theMessage->eventID() == aCreatedEvent && aFeatures.size() > 1) { + featuresOrderedByCreation(aFeatures, anOrderedFeatures); + } else { // order is not important, just process features before constraints + featuresOrderedByType(aFeatures, anOrderedFeatures, aSketchFeature); + } + + IndexedFeatureMap::iterator aFeat; + for (aFeat = anOrderedFeatures.begin(); aFeat != anOrderedFeatures.end(); aFeat++) { + updateFeature(aFeat->second); } + updateSketch(aSketchFeature); } 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()); + AttributePtr aMovedAttribute = aMoveMsg->movedAttribute(); + int aMovedPoint = aMoveMsg->movedPointIndex(); const std::shared_ptr& aFrom = aMoveMsg->originalPosition(); const std::shared_ptr& aTo = aMoveMsg->currentPosition(); @@ -141,20 +206,21 @@ void SketchSolver_Manager::processEvent( std::dynamic_pointer_cast(aMovedFeature); if (aSketchFeature && !aSketchFeature->isMacro()) needToResolve = moveFeature(aSketchFeature, aFrom, aTo); - } else if (aMovedPoint) - needToResolve = moveAttribute(aMovedPoint, aFrom, aTo); + } else if (aMovedAttribute) + needToResolve = moveAttribute(aMovedAttribute, 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()) { @@ -172,6 +238,35 @@ void SketchSolver_Manager::processEvent( } myIsComputed = false; } + else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_GET_DOF_OBJECTS)) { + std::shared_ptr anUpdateMsg = + std::dynamic_pointer_cast(theMessage); + std::set aObjects = anUpdateMsg->objects(); + if (aObjects.size() == 1) { + std::set::const_iterator aIt; + for (aIt = aObjects.cbegin(); aIt != aObjects.cend(); aIt++) { + CompositeFeaturePtr aFeature = + std::dynamic_pointer_cast(*aIt); + if (aFeature) { + SketchGroupPtr aGroup = findGroup(aFeature); + + std::set aFreeFeatures; + aGroup->underconstrainedFeatures(aFreeFeatures); + + std::list aFeatures; + std::set::const_iterator aIt; + for (aIt = aFreeFeatures.cbegin(); aIt != aFreeFeatures.cend(); ++aIt) { + aFeatures.push_back(*aIt); + } + + // send features to GUI + static const Events_ID anEvent = Events_Loop::eventByName(EVENT_DOF_OBJECTS); + ModelAPI_EventCreator::get()->sendUpdated(aFeatures, anEvent); + Events_Loop::loop()->flush(anEvent); + } + } + } + } // resolve constraints if needed bool needToUpdate = needToResolve && resolveConstraints(); @@ -188,6 +283,25 @@ void SketchSolver_Manager::processEvent( Events_Loop::loop()->flush(anUpdateEvent); } +// ============================================================================ +// Function: updateSketch +// Purpose: update sketch plane in appropriate group +// ============================================================================ +bool SketchSolver_Manager::updateSketch(const CompositeFeaturePtr& theSketch) +{ + if (!theSketch) + return true; + + bool isOk = true; + std::list::const_iterator aGroupIt; + for (aGroupIt = myGroups.begin(); aGroupIt != myGroups.end(); ++aGroupIt) + if ((*aGroupIt)->getWorkplane() == theSketch) { + (*aGroupIt)->updateSketch(theSketch); + break; + } + return isOk; +} + // ============================================================================ // Function: updateFeature // Purpose: create/update constraint or feature in appropriate group @@ -226,6 +340,20 @@ bool SketchSolver_Manager::moveFeature( 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); } @@ -235,23 +363,33 @@ bool SketchSolver_Manager::moveFeature( // Purpose: move given attribute in appropriate group // ============================================================================ bool SketchSolver_Manager::moveAttribute( - const std::shared_ptr& theMovedAttribute, + const std::shared_ptr& theMovedAttribute, + const int theMovedPointIndex, 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) + { + setPoint(theMovedAttribute, theMovedPointIndex, 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); + setPoint(theMovedAttribute, theMovedPointIndex, theTo); return false; } aGroup->blockEvents(true); - return aGroup->movePoint(theMovedAttribute, theFrom, theTo); + return aGroup->movePoint(theMovedAttribute, theMovedPointIndex, theFrom, theTo); } // ============================================================================ @@ -259,7 +397,7 @@ bool SketchSolver_Manager::moveAttribute( // Purpose: search groups of entities interacting with given feature // ============================================================================ SketchGroupPtr SketchSolver_Manager::findGroup( - std::shared_ptr theFeature) + std::shared_ptr theFeature) { if (!isFeatureValid(theFeature)) return SketchGroupPtr(); // do not process wrong features @@ -275,17 +413,21 @@ SketchGroupPtr SketchSolver_Manager::findGroup( break; } } + return findGroup(aSketch); +} - if (!aSketch) +SketchGroupPtr SketchSolver_Manager::findGroup(CompositeFeaturePtr theSketch) +{ + if (!theSketch) return SketchGroupPtr(); // not a sketch's feature std::list::const_iterator aGroupIt; for (aGroupIt = myGroups.begin(); aGroupIt != myGroups.end(); ++aGroupIt) - if ((*aGroupIt)->getWorkplane() == aSketch) + if ((*aGroupIt)->getWorkplane() == theSketch) return *aGroupIt; // group for the sketch does not created yet - SketchGroupPtr aNewGroup = SketchGroupPtr(new SketchSolver_Group(aSketch)); + SketchGroupPtr aNewGroup = SketchGroupPtr(new SketchSolver_Group(theSketch)); myGroups.push_back(aNewGroup); return aNewGroup; }