X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSketchSolver%2FSketchSolver_ConstraintManager.cpp;h=682bbf23a48fdb89cbf4602e7e62115e9c5b045d;hb=506a83727ca8f8297fc1dcdf4ea40d7865c35450;hp=e54a41292763daec52ac101d8d6bbbe10bcccbeb;hpb=38afbd899a8645c83e17f2c24a17a2b7414911b4;p=modules%2Fshaper.git diff --git a/src/SketchSolver/SketchSolver_ConstraintManager.cpp b/src/SketchSolver/SketchSolver_ConstraintManager.cpp index e54a41292..682bbf23a 100644 --- a/src/SketchSolver/SketchSolver_ConstraintManager.cpp +++ b/src/SketchSolver/SketchSolver_ConstraintManager.cpp @@ -5,7 +5,6 @@ // Author: Artem ZHIDKOV #include "SketchSolver_ConstraintManager.h" -#include #include #include @@ -35,6 +34,7 @@ SketchSolver_ConstraintManager* SketchSolver_ConstraintManager::_self = 0; /// Global constraint manager object SketchSolver_ConstraintManager* myManager = SketchSolver_ConstraintManager::Instance(); + // ======================================================== // ========= SketchSolver_ConstraintManager =============== // ======================================================== @@ -79,57 +79,57 @@ void SketchSolver_ConstraintManager::processEvent( std::dynamic_pointer_cast(theMessage); std::set aFeatures = anUpdateMsg->objects(); + // Shows the message has at least one feature applicable for solver + bool hasProperFeature = false; + bool isMovedEvt = theMessage->eventID() - == Events_Loop::loop()->eventByName(EVENT_OBJECT_MOVED); + == Events_Loop::loop()->eventByName(EVENT_OBJECT_MOVED); if (isMovedEvt) { std::set::iterator aFeatIter; for (aFeatIter = aFeatures.begin(); aFeatIter != aFeatures.end(); aFeatIter++) { std::shared_ptr aSFeature = std::dynamic_pointer_cast(*aFeatIter); - if (aSFeature) - updateEntity(aSFeature); + if (aSFeature) { + moveEntity(aSFeature); + hasProperFeature = true; + } } } 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 = std::dynamic_pointer_cast(*aFeatIter); - if (!aFeature) + std::list aSketchFeatures = SketchSolver_Group::selectApplicableFeatures(aFeatures); + std::list::iterator aFeatIter = aSketchFeatures.begin(); + for (; aFeatIter != aSketchFeatures.end(); ++aFeatIter) { + if ((*aFeatIter)->getKind() == SketchPlugin_Sketch::ID()) { + std::shared_ptr aSketch = + std::dynamic_pointer_cast(*aFeatIter); + hasProperFeature = changeWorkplane(aSketch) || hasProperFeature; continue; - const std::string& aFeatureKind = aFeature->getKind(); - if (aFeatureKind.compare(SketchPlugin_Sketch::ID()) == 0) { - std::shared_ptr aSketch = std::dynamic_pointer_cast< - ModelAPI_CompositeFeature>(aFeature); - changeWorkplane(aSketch); } - } - // then get anything but not the sketch - for (aFeatIter = aFeatures.begin(); aFeatIter != aFeatures.end(); aFeatIter++) { std::shared_ptr aFeature = - std::dynamic_pointer_cast(*aFeatIter); + std::dynamic_pointer_cast(*aFeatIter); if (!aFeature) continue; - changeConstraintOrEntity(aFeature); + hasProperFeature = changeConstraintOrEntity(aFeature) || hasProperFeature; } } // Solve the set of constraints - resolveConstraints(); + if (hasProperFeature) + resolveConstraints(isMovedEvt); // send update for movement in any case } else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_DELETED)) { std::shared_ptr aDeleteMsg = - std::dynamic_pointer_cast(theMessage); + 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 std::set::const_iterator aFGrIter; for (aFGrIter = aFeatureGroups.begin(); aFGrIter != aFeatureGroups.end(); aFGrIter++) if (aFGrIter->compare(ModelAPI_ResultConstruction::group()) == 0 || - aFGrIter->compare(ModelAPI_Feature::group()) == 0) + aFGrIter->compare(ModelAPI_Feature::group()) == 0) break; if (aFGrIter != aFeatureGroups.end()) { - std::vector::iterator aGroupIter = myGroups.begin(); - std::vector aSeparatedGroups; + std::vector::iterator aGroupIter = myGroups.begin(); + std::vector aSeparatedGroups; while (aGroupIter != myGroups.end()) { if (!(*aGroupIter)->isWorkplaneValid()) { // the group should be removed delete *aGroupIter; @@ -138,7 +138,7 @@ void SketchSolver_ConstraintManager::processEvent( aGroupIter = myGroups.begin() + aShift; continue; } - if ((*aGroupIter)->updateGroup()) { // some constraints were removed, try to split the group + if (!(*aGroupIter)->isConsistent()) { // some constraints were removed, try to split the group (*aGroupIter)->splitGroup(aSeparatedGroups); } aGroupIter++; @@ -154,13 +154,12 @@ void SketchSolver_ConstraintManager::processEvent( // Class: SketchSolver_Session // Purpose: update workplane by given parameters of the sketch // ============================================================================ -bool SketchSolver_ConstraintManager::changeWorkplane( - std::shared_ptr theSketch) +bool SketchSolver_ConstraintManager::changeWorkplane(CompositeFeaturePtr theSketch) { bool aResult = true; // changed when a workplane wrongly updated bool isUpdated = false; // Try to update specified workplane in all groups - std::vector::iterator aGroupIter; + std::vector::iterator aGroupIter; for (aGroupIter = myGroups.begin(); aGroupIter != myGroups.end(); aGroupIter++) if ((*aGroupIter)->isBaseWorkplane(theSketch)) { isUpdated = true; @@ -169,7 +168,7 @@ bool SketchSolver_ConstraintManager::changeWorkplane( } // If the workplane is not updated, so this is a new workplane if (!isUpdated) { - SketchSolver_ConstraintGroup* aNewGroup = new SketchSolver_ConstraintGroup(theSketch); + SketchSolver_Group* aNewGroup = new SketchSolver_Group(theSketch); // Verify that the group is created successfully if (!aNewGroup->isBaseWorkplane(theSketch) || !aNewGroup->isWorkplaneValid()) { delete aNewGroup; @@ -203,7 +202,7 @@ bool SketchSolver_ConstraintManager::changeConstraintOrEntity( std::shared_ptr aWP = findWorkplane(aConstraint); if (!aWP) return false; - SketchSolver_ConstraintGroup* aGroup = new SketchSolver_ConstraintGroup(aWP); + SketchSolver_Group* aGroup = new SketchSolver_Group(aWP); if (!aGroup->changeConstraint(aConstraint)) { delete aGroup; return false; @@ -212,19 +211,19 @@ bool SketchSolver_ConstraintManager::changeConstraintOrEntity( return true; } else if (aGroups.size() == 1) { // Only one group => add feature into it Slvs_hGroup aGroupId = *(aGroups.begin()); - std::vector::iterator aGroupIter; + std::vector::iterator aGroupIter; for (aGroupIter = myGroups.begin(); aGroupIter != myGroups.end(); aGroupIter++) if ((*aGroupIter)->getId() == aGroupId) { // If the group is empty, the feature is not added (the constraint only) if (!aConstraint && !(*aGroupIter)->isEmpty()) - return (*aGroupIter)->changeEntityFeature(theFeature) != SLVS_E_UNKNOWN; + return (*aGroupIter)->updateFeature(theFeature); return (*aGroupIter)->changeConstraint(aConstraint); } } else if (aGroups.size() > 1) { // Several groups applicable for this feature => need to merge them std::set::const_iterator aGroupsIter = aGroups.begin(); // Search first group - std::vector::iterator aFirstGroupIter; + std::vector::iterator aFirstGroupIter; for (aFirstGroupIter = myGroups.begin(); aFirstGroupIter != myGroups.end(); aFirstGroupIter++) if ((*aFirstGroupIter)->getId() == *aGroupsIter) break; @@ -232,7 +231,7 @@ bool SketchSolver_ConstraintManager::changeConstraintOrEntity( return false; // Append other groups to the first one - std::vector::iterator anOtherGroupIter = aFirstGroupIter + 1; + std::vector::iterator anOtherGroupIter = aFirstGroupIter + 1; for (aGroupsIter++; aGroupsIter != aGroups.end(); aGroupsIter++) { for (; anOtherGroupIter != myGroups.end(); anOtherGroupIter++) if ((*anOtherGroupIter)->getId() == *aGroupsIter) @@ -253,7 +252,7 @@ bool SketchSolver_ConstraintManager::changeConstraintOrEntity( if (aConstraint) return (*aFirstGroupIter)->changeConstraint(aConstraint); - return (*aFirstGroupIter)->changeEntityFeature(theFeature) != SLVS_E_UNKNOWN; + return (*aFirstGroupIter)->updateFeature(theFeature); } // Something goes wrong @@ -261,54 +260,17 @@ bool SketchSolver_ConstraintManager::changeConstraintOrEntity( } // ============================================================================ -// Function: updateEntity +// Function: moveEntity // Class: SketchSolver_Session -// Purpose: update any element on the sketch, which is used by constraints +// Purpose: update element moved on the sketch, which is used by constraints // ============================================================================ -void SketchSolver_ConstraintManager::updateEntity( +void SketchSolver_ConstraintManager::moveEntity( std::shared_ptr theFeature) { - // Create list of attributes depending on type of the feature - std::vector anAttrList; - const std::string& aFeatureKind = theFeature->getKind(); - // Point - if (aFeatureKind.compare(SketchPlugin_Point::ID()) == 0) - anAttrList.push_back(SketchPlugin_Point::COORD_ID()); - // Line - else if (aFeatureKind.compare(SketchPlugin_Line::ID()) == 0) { - anAttrList.push_back(SketchPlugin_Line::START_ID()); - anAttrList.push_back(SketchPlugin_Line::END_ID()); - } - // Circle - else if (aFeatureKind.compare(SketchPlugin_Circle::ID()) == 0) { - anAttrList.push_back(SketchPlugin_Circle::CENTER_ID()); - anAttrList.push_back(SketchPlugin_Circle::RADIUS_ID()); - } - // Arc - else if (aFeatureKind.compare(SketchPlugin_Arc::ID()) == 0) { - anAttrList.push_back(SketchPlugin_Arc::CENTER_ID()); - anAttrList.push_back(SketchPlugin_Arc::START_ID()); - anAttrList.push_back(SketchPlugin_Arc::END_ID()); - } - /// \todo Other types of features should be implemented - - // Check changing of feature's attributes (go through the groups and search usage of the attributes) - std::vector::const_iterator anAttrIter; - for (anAttrIter = anAttrList.begin(); anAttrIter != anAttrList.end(); anAttrIter++) { - std::vector::iterator aGroupIter; - for (aGroupIter = myGroups.begin(); aGroupIter != myGroups.end(); aGroupIter++) { - if ((*aGroupIter)->isEmpty()) - continue; - std::shared_ptr anAttribute = std::dynamic_pointer_cast< - ModelAPI_Attribute>(theFeature->data()->attribute(*anAttrIter)); - (*aGroupIter)->updateEntityIfPossible(anAttribute); - } - } - - std::vector::iterator aGroupIter; - for (aGroupIter = myGroups.begin(); aGroupIter != myGroups.end(); aGroupIter++) - if (!(*aGroupIter)->isEmpty()) - (*aGroupIter)->updateRelatedConstraintsFeature(theFeature); + std::vector::iterator aGroupIt = myGroups.begin(); + for (; aGroupIt != myGroups.end(); aGroupIt++) + if (!(*aGroupIt)->isEmpty() && (*aGroupIt)->isInteract(theFeature)) + (*aGroupIt)->moveFeature(theFeature); } // ============================================================================ @@ -322,8 +284,8 @@ void SketchSolver_ConstraintManager::findGroups( { std::shared_ptr aWP = findWorkplane(theFeature); - SketchSolver_ConstraintGroup* anEmptyGroup = 0; // appropriate empty group for specified constraint - std::vector::const_iterator aGroupIter; + SketchSolver_Group* anEmptyGroup = 0; // appropriate empty group for specified constraint + std::vector::const_iterator aGroupIter; for (aGroupIter = myGroups.begin(); aGroupIter != myGroups.end(); aGroupIter++) if (aWP == (*aGroupIter)->getWorkplane() && (*aGroupIter)->isInteract(theFeature)) { if (!(*aGroupIter)->isEmpty()) @@ -348,19 +310,22 @@ std::shared_ptr SketchSolver_ConstraintManager // Already verified workplanes std::set > aVerified; - std::vector::const_iterator aGroupIter; + std::vector::const_iterator aGroupIter; for (aGroupIter = myGroups.begin(); aGroupIter != myGroups.end(); aGroupIter++) { std::shared_ptr aWP = (*aGroupIter)->getWorkplane(); if (aVerified.find(aWP) != aVerified.end()) continue; - 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; - for (anIter = aFeaturesList.begin(); anIter != aFeaturesList.end(); anIter++) - if (*anIter == theFeature) - return aWP; // workplane is found + DataPtr aData = aWP->data(); + if (aData->isValid()) { + std::shared_ptr aWPFeatures = std::dynamic_pointer_cast< + ModelAPI_AttributeRefList>(aData->attribute(SketchPlugin_Sketch::FEATURES_ID())); + std::list aFeaturesList = aWPFeatures->list(); + std::list::const_iterator anIter; + for (anIter = aFeaturesList.begin(); anIter != aFeaturesList.end(); anIter++) + if (*anIter == theFeature) + return aWP; // workplane is found + } aVerified.insert(aWP); } @@ -372,7 +337,7 @@ std::shared_ptr SketchSolver_ConstraintManager // 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; @@ -383,17 +348,20 @@ void SketchSolver_ConstraintManager::resolveConstraints() Events_Loop::loop()->setFlushed(anUpdateEvent, false); } - std::vector::iterator aGroupIter; + std::vector::iterator aGroupIter; for (aGroupIter = myGroups.begin(); aGroupIter != myGroups.end(); aGroupIter++) if ((*aGroupIter)->resolveConstraints()) needToUpdate = true; - // Features may be updated => now send events, btu for all changed at once + // Features may be updated => now send events, but for all changed at once if (isUpdateFlushed) { Events_Loop::loop()->setFlushed(anUpdateEvent, true); } - if (needToUpdate) - Events_Loop::loop()->flush(anUpdateEvent); + // 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); }