X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSketchSolver%2FSketchSolver_ConstraintManager.cpp;h=71f062c392a6a3de9537a2c31ed20066c6a36929;hb=51889d235a27d0ee4b3c3237d21d1ea621063580;hp=ebc25b1fa35edf7dbbb20e78b976258937cd914c;hpb=add875fff5ce228a4914fcc323fdb911a1042b21;p=modules%2Fshaper.git diff --git a/src/SketchSolver/SketchSolver_ConstraintManager.cpp b/src/SketchSolver/SketchSolver_ConstraintManager.cpp index ebc25b1fa..71f062c39 100644 --- a/src/SketchSolver/SketchSolver_ConstraintManager.cpp +++ b/src/SketchSolver/SketchSolver_ConstraintManager.cpp @@ -1,8 +1,11 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D + // File: SketchSolver_ConstraintManager.cpp // Created: 08 May 2014 // Author: Artem ZHIDKOV #include "SketchSolver_ConstraintManager.h" +#include #include #include @@ -11,6 +14,7 @@ #include #include #include +#include #include @@ -19,8 +23,11 @@ #include #include #include +#include #include +#include +#include // Initialization of constraint manager self pointer SketchSolver_ConstraintManager* SketchSolver_ConstraintManager::_self = 0; @@ -41,6 +48,7 @@ SketchSolver_ConstraintManager* SketchSolver_ConstraintManager::Instance() SketchSolver_ConstraintManager::SketchSolver_ConstraintManager() { myGroups.clear(); + myIsComputed = false; // Register in event loop Events_Loop::loop()->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_CREATED)); @@ -60,13 +68,15 @@ SketchSolver_ConstraintManager::~SketchSolver_ConstraintManager() // Purpose: listen the event loop and process the message // ============================================================================ void SketchSolver_ConstraintManager::processEvent( - const boost::shared_ptr& theMessage) + const std::shared_ptr& theMessage) { + 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)) { - boost::shared_ptr anUpdateMsg = - boost::dynamic_pointer_cast(theMessage); + std::shared_ptr anUpdateMsg = + std::dynamic_pointer_cast(theMessage); std::set aFeatures = anUpdateMsg->objects(); bool isMovedEvt = theMessage->eventID() @@ -74,39 +84,40 @@ void SketchSolver_ConstraintManager::processEvent( if (isMovedEvt) { std::set::iterator aFeatIter; for (aFeatIter = aFeatures.begin(); aFeatIter != aFeatures.end(); aFeatIter++) { - boost::shared_ptr aSFeature = - boost::dynamic_pointer_cast(*aFeatIter); + std::shared_ptr aSFeature = + std::dynamic_pointer_cast(*aFeatIter); if (aSFeature) updateEntity(aSFeature); } } 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); + FeaturePtr aFeature = std::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< + std::shared_ptr aSketch = std::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++) { + std::shared_ptr aFeature = + std::dynamic_pointer_cast(*aFeatIter); + if (!aFeature) + continue; + changeConstraintOrEntity(aFeature); } } // Solve the set of constraints - resolveConstraints(); + resolveConstraints(isMovedEvt); // send update for movement in any case } else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_DELETED)) { - boost::shared_ptr aDeleteMsg = - boost::dynamic_pointer_cast(theMessage); + std::shared_ptr aDeleteMsg = + std::dynamic_pointer_cast(theMessage); const std::set& aFeatureGroups = aDeleteMsg->groups(); // Find SketchPlugin_Sketch::ID() in groups. The constraint groups should be updated when an object removed from Sketch @@ -144,7 +155,7 @@ void SketchSolver_ConstraintManager::processEvent( // Purpose: update workplane by given parameters of the sketch // ============================================================================ bool SketchSolver_ConstraintManager::changeWorkplane( - boost::shared_ptr theSketch) + std::shared_ptr theSketch) { bool aResult = true; // changed when a workplane wrongly updated bool isUpdated = false; @@ -160,7 +171,7 @@ bool SketchSolver_ConstraintManager::changeWorkplane( if (!isUpdated) { SketchSolver_ConstraintGroup* aNewGroup = new SketchSolver_ConstraintGroup(theSketch); // Verify that the group is created successfully - if (!aNewGroup->isBaseWorkplane(theSketch)) { + if (!aNewGroup->isBaseWorkplane(theSketch) || !aNewGroup->isWorkplaneValid()) { delete aNewGroup; return false; } @@ -175,21 +186,21 @@ bool SketchSolver_ConstraintManager::changeWorkplane( // Purpose: create/update the constraint or the feature and place it into appropriate group // ============================================================================ bool SketchSolver_ConstraintManager::changeConstraintOrEntity( - boost::shared_ptr theFeature) + std::shared_ptr theFeature) { // Search the groups which this feature touches std::set aGroups; findGroups(theFeature, aGroups); - boost::shared_ptr aConstraint = - boost::dynamic_pointer_cast(theFeature); + std::shared_ptr aConstraint = + std::dynamic_pointer_cast(theFeature); // Process the groups list if (aGroups.size() == 0) { // There are no groups applicable for this constraint => create new one // The group will be created only for constraints, not for features if (!aConstraint) return false; - boost::shared_ptr aWP = findWorkplane(aConstraint); + std::shared_ptr aWP = findWorkplane(aConstraint); if (!aWP) return false; SketchSolver_ConstraintGroup* aGroup = new SketchSolver_ConstraintGroup(aWP); @@ -206,7 +217,7 @@ bool SketchSolver_ConstraintManager::changeConstraintOrEntity( if ((*aGroupIter)->getId() == aGroupId) { // If the group is empty, the feature is not added (the constraint only) if (!aConstraint && !(*aGroupIter)->isEmpty()) - return (*aGroupIter)->changeEntity(theFeature) != SLVS_E_UNKNOWN; + return (*aGroupIter)->changeEntityFeature(theFeature) != SLVS_E_UNKNOWN; return (*aGroupIter)->changeConstraint(aConstraint); } } else if (aGroups.size() > 1) { // Several groups applicable for this feature => need to merge them @@ -242,7 +253,7 @@ bool SketchSolver_ConstraintManager::changeConstraintOrEntity( if (aConstraint) return (*aFirstGroupIter)->changeConstraint(aConstraint); - return (*aFirstGroupIter)->changeEntity(theFeature) != SLVS_E_UNKNOWN; + return (*aFirstGroupIter)->changeEntityFeature(theFeature) != SLVS_E_UNKNOWN; } // Something goes wrong @@ -255,7 +266,7 @@ bool SketchSolver_ConstraintManager::changeConstraintOrEntity( // Purpose: update any element on the sketch, which is used by constraints // ============================================================================ void SketchSolver_ConstraintManager::updateEntity( - boost::shared_ptr theFeature) + std::shared_ptr theFeature) { // Create list of attributes depending on type of the feature std::vector anAttrList; @@ -288,7 +299,7 @@ void SketchSolver_ConstraintManager::updateEntity( for (aGroupIter = myGroups.begin(); aGroupIter != myGroups.end(); aGroupIter++) { if ((*aGroupIter)->isEmpty()) continue; - boost::shared_ptr anAttribute = boost::dynamic_pointer_cast< + std::shared_ptr anAttribute = std::dynamic_pointer_cast< ModelAPI_Attribute>(theFeature->data()->attribute(*anAttrIter)); (*aGroupIter)->updateEntityIfPossible(anAttribute); } @@ -297,7 +308,7 @@ void SketchSolver_ConstraintManager::updateEntity( std::vector::iterator aGroupIter; for (aGroupIter = myGroups.begin(); aGroupIter != myGroups.end(); aGroupIter++) if (!(*aGroupIter)->isEmpty()) - (*aGroupIter)->updateRelatedConstraints(theFeature); + (*aGroupIter)->updateRelatedConstraintsFeature(theFeature); } // ============================================================================ @@ -306,10 +317,10 @@ void SketchSolver_ConstraintManager::updateEntity( // Purpose: search groups of entities interacting with given feature // ============================================================================ void SketchSolver_ConstraintManager::findGroups( - boost::shared_ptr theFeature, + std::shared_ptr theFeature, std::set& theGroupIDs) const { - boost::shared_ptr aWP = findWorkplane(theFeature); + std::shared_ptr aWP = findWorkplane(theFeature); SketchSolver_ConstraintGroup* anEmptyGroup = 0; // appropriate empty group for specified constraint std::vector::const_iterator aGroupIter; @@ -331,19 +342,19 @@ void SketchSolver_ConstraintManager::findGroups( // Class: SketchSolver_Session // Purpose: search workplane containing given feature // ============================================================================ -boost::shared_ptr SketchSolver_ConstraintManager::findWorkplane( - boost::shared_ptr theFeature) const +std::shared_ptr SketchSolver_ConstraintManager +::findWorkplane(std::shared_ptr theFeature) const { // Already verified workplanes - std::set > aVerified; + std::set > aVerified; std::vector::const_iterator aGroupIter; for (aGroupIter = myGroups.begin(); aGroupIter != myGroups.end(); aGroupIter++) { - boost::shared_ptr aWP = (*aGroupIter)->getWorkplane(); + std::shared_ptr aWP = (*aGroupIter)->getWorkplane(); if (aVerified.find(aWP) != aVerified.end()) continue; - boost::shared_ptr aWPFeatures = boost::dynamic_pointer_cast< + std::shared_ptr aWPFeatures = std::dynamic_pointer_cast< ModelAPI_AttributeRefList>(aWP->data()->attribute(SketchPlugin_Sketch::FEATURES_ID())); std::list aFeaturesList = aWPFeatures->list(); std::list::const_iterator anIter; @@ -353,7 +364,7 @@ boost::shared_ptr SketchSolver_ConstraintManager::fin aVerified.insert(aWP); } - return boost::shared_ptr(); + return std::shared_ptr(); } // ============================================================================ @@ -361,16 +372,31 @@ boost::shared_ptr SketchSolver_ConstraintManager::fin // Class: SketchSolver_Session // Purpose: change entities according to available constraints // ============================================================================ -void SketchSolver_ConstraintManager::resolveConstraints() +void SketchSolver_ConstraintManager::resolveConstraints(const bool theForceUpdate) { + myIsComputed = true; bool needToUpdate = false; + static Events_ID anUpdateEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED); + // to avoid redisplay of each segment on update by solver one by one in the viewer + bool isUpdateFlushed = Events_Loop::loop()->isFlushed(anUpdateEvent); + if (isUpdateFlushed) { + Events_Loop::loop()->setFlushed(anUpdateEvent, false); + } + std::vector::iterator aGroupIter; for (aGroupIter = myGroups.begin(); aGroupIter != myGroups.end(); aGroupIter++) if ((*aGroupIter)->resolveConstraints()) needToUpdate = true; - // Features may be updated => send events - if (needToUpdate) - Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED)); + // Features may be updated => now send events, but for all changed at once + if (isUpdateFlushed) { + Events_Loop::loop()->setFlushed(anUpdateEvent, true); + } + // Must be before flush because on "Updated" flush the results may be produced + // and the creation event is appeared with many new objects. If myIsComputed these + // events are missed in processEvents and some elements are not added. + myIsComputed = false; + if (needToUpdate || theForceUpdate) + Events_Loop::loop()->flush(anUpdateEvent); }