-// 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<mailto:webmaster.salome@opencascade.com>
+//
#include "SketchSolver_Manager.h"
+#include "SketchSolver_Error.h"
#include <Events_Loop.h>
-#include <ModelAPI_AttributeDouble.h>
-#include <ModelAPI_AttributeRefList.h>
-#include <ModelAPI_Data.h>
+#include <GeomDataAPI_Point2D.h>
#include <ModelAPI_Events.h>
-#include <ModelAPI_Object.h>
#include <ModelAPI_ResultConstruction.h>
-#include <ModelAPI_Attribute.h>
-
+#include <ModelAPI_Session.h>
+#include <ModelAPI_Validator.h>
#include <SketchPlugin_Constraint.h>
-
-#include <SketchPlugin_Arc.h>
-#include <SketchPlugin_Circle.h>
-#include <SketchPlugin_Line.h>
-#include <SketchPlugin_Point.h>
#include <SketchPlugin_Sketch.h>
-#include <SketchPlugin_Feature.h>
-#include <list>
-#include <set>
-#include <memory>
+/// Global constraint manager object
+static SketchSolver_Manager* myManager = SketchSolver_Manager::instance();
-static const Events_ID anUpdateEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED);
+/// \brief Verifies is the feature valid
+static bool isFeatureValid(FeaturePtr theFeature)
+{
+ if (!theFeature || !theFeature->data() || !theFeature->data()->isValid())
+ return false;
-// Initialization of constraint manager self pointer
-SketchSolver_Manager* SketchSolver_Manager::mySelf = 0;
+ SessionPtr aMgr = ModelAPI_Session::get();
+ ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
+ return aFactory->validate(theFeature);
+}
-/// Global constraint manager object
-SketchSolver_Manager* myManager = SketchSolver_Manager::instance();
// ========================================================
// ========================================================
SketchSolver_Manager* SketchSolver_Manager::instance()
{
+ static SketchSolver_Manager* mySelf = 0; // Self pointer to implement singleton functionality
if (!mySelf)
mySelf = new SketchSolver_Manager();
return mySelf;
Events_Loop::loop()->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
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_SKETCH_PREPARED));
}
SketchSolver_Manager::~SketchSolver_Manager()
myGroups.clear();
}
-void SketchSolver_Manager::setBuilder(BuilderPtr theBuilder)
+bool SketchSolver_Manager::groupMessages()
{
- myBuilder = theBuilder;
-}
-
-BuilderPtr SketchSolver_Manager::builder()
-{
- return myBuilder;
+ return true;
}
// ============================================================================
void SketchSolver_Manager::processEvent(
const std::shared_ptr<Events_Message>& theMessage)
{
+ bool needToResolve = false;
+ bool isUpdateFlushed = false;
+ bool isMovedEvt = false;
+
+ 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
+ // are collected and must be processed by the solver
+ if (theMessage->eventID() == aSketchPreparedEvent) {
+ flushGrouped(anUpdateEvent);
+ needToResolve = true;
+ }
+
if (myIsComputed)
return;
myIsComputed = true;
+
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)) {
+ || theMessage->eventID() == anUpdateEvent) {
std::shared_ptr<ModelAPI_ObjectUpdatedMessage> anUpdateMsg =
std::dynamic_pointer_cast<ModelAPI_ObjectUpdatedMessage>(theMessage);
std::set<ObjectPtr> aFeatures = anUpdateMsg->objects();
- bool isUpdateFlushed = stopSendUpdate();
- // 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);
- if (isMovedEvt) {
- std::set<ObjectPtr>::iterator aFeatIter;
- for (aFeatIter = aFeatures.begin(); aFeatIter != aFeatures.end(); aFeatIter++) {
- std::shared_ptr<SketchPlugin_Feature> aSFeature =
- std::dynamic_pointer_cast<SketchPlugin_Feature>(*aFeatIter);
- if (aSFeature) {
- moveEntity(aSFeature);
- hasProperFeature = true;
- }
- }
- } else {
- std::list<FeaturePtr> aSketchFeatures = SketchSolver_Group::selectApplicableFeatures(aFeatures);
- std::list<FeaturePtr>::iterator aFeatIter = aSketchFeatures.begin();
- for (; aFeatIter != aSketchFeatures.end(); ++aFeatIter) {
- if ((*aFeatIter)->getKind() == SketchPlugin_Sketch::ID()) {
- std::shared_ptr<ModelAPI_CompositeFeature> aSketch =
- std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(*aFeatIter);
- hasProperFeature = changeWorkplane(aSketch) || hasProperFeature;
- continue;
- }
- std::shared_ptr<SketchPlugin_Feature> aFeature =
- std::dynamic_pointer_cast<SketchPlugin_Feature>(*aFeatIter);
- if (!aFeature)
- continue;
- hasProperFeature = changeFeature(aFeature) || hasProperFeature;
- }
+ isUpdateFlushed = stopSendUpdate();
+
+ // update sketch features only
+ std::set<ObjectPtr>::iterator aFeatIter;
+ for (aFeatIter = aFeatures.begin(); aFeatIter != aFeatures.end(); aFeatIter++) {
+ std::shared_ptr<SketchPlugin_Feature> aFeature =
+ std::dynamic_pointer_cast<SketchPlugin_Feature>(*aFeatIter);
+ if (!aFeature || aFeature->isMacro())
+ continue;
+
+ updateFeature(aFeature);
}
- bool needToUpdate = false;
- // Solve the set of constraints
- if (hasProperFeature)
- needToUpdate = resolveConstraints();
+ } else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_MOVED)) {
+ std::shared_ptr<ModelAPI_ObjectMovedMessage> aMoveMsg =
+ std::dynamic_pointer_cast<ModelAPI_ObjectMovedMessage>(theMessage);
+
+ ObjectPtr aMovedObject = aMoveMsg->movedObject();
+ std::shared_ptr<GeomDataAPI_Point2D> aMovedPoint =
+ std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aMoveMsg->movedAttribute());
+
+ const std::shared_ptr<GeomAPI_Pnt2d>& aFrom = aMoveMsg->originalPosition();
+ const std::shared_ptr<GeomAPI_Pnt2d>& aTo = aMoveMsg->currentPosition();
- // Features may be updated => now send events, but for all changed at once
- if (isUpdateFlushed)
- allowSendUpdate();
- // send update for movement in any case
- if (needToUpdate || isMovedEvt)
- Events_Loop::loop()->flush(anUpdateEvent);
+ if (aMovedObject) {
+ FeaturePtr aMovedFeature = ModelAPI_Feature::feature(aMovedObject);
+ std::shared_ptr<SketchPlugin_Feature> aSketchFeature =
+ std::dynamic_pointer_cast<SketchPlugin_Feature>(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<ModelAPI_ObjectDeletedMessage> aDeleteMsg =
std::dynamic_pointer_cast<ModelAPI_ObjectDeletedMessage>(theMessage);
const std::set<std::string>& aFeatureGroups = aDeleteMsg->groups();
- // Find SketchPlugin_Sketch::ID() in groups. The constraint groups should be updated when an object removed from Sketch
+ // Find SketchPlugin_Sketch::ID() in groups.
+ // The constraint groups should be updated when an object removed from Sketch
std::set<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)
+ aFGrIter->compare(ModelAPI_Feature::group()) == 0)
break;
if (aFGrIter != aFeatureGroups.end()) {
- std::vector<SketchSolver_Group*>::iterator aGroupIter = myGroups.begin();
- std::list<SketchSolver_Group*> aSeparatedGroups;
+ std::list<SketchGroupPtr>::iterator aGroupIter = myGroups.begin();
while (aGroupIter != myGroups.end()) {
if (!(*aGroupIter)->isWorkplaneValid()) { // the group should be removed
- delete *aGroupIter;
- int aShift = aGroupIter - myGroups.begin();
- myGroups.erase(aGroupIter);
- aGroupIter = myGroups.begin() + aShift;
+ std::list<SketchGroupPtr>::iterator aRemoveIt = aGroupIter++;
+ myGroups.erase(aRemoveIt);
continue;
}
- if (!(*aGroupIter)->isConsistent()) { // some constraints were removed, try to split the group
- (*aGroupIter)->splitGroup(aSeparatedGroups);
- }
- aGroupIter++;
+
+ (*aGroupIter)->repairConsistency();
+ ++aGroupIter;
}
- if (aSeparatedGroups.size() > 0)
- myGroups.insert(myGroups.end(), aSeparatedGroups.begin(), aSeparatedGroups.end());
}
+ myIsComputed = false;
}
+
+ // resolve constraints if needed
+ bool needToUpdate = needToResolve && resolveConstraints();
+ releaseFeaturesIfEventsBlocked();
+
+ // Features may be updated => now send events, but for all changed at once
+ if (isUpdateFlushed)
+ allowSendUpdate();
+
myIsComputed = false;
+
+ // send update for movement in any case
+ if (needToUpdate || isMovedEvt)
+ Events_Loop::loop()->flush(anUpdateEvent);
}
// ============================================================================
-// Function: changeWorkplane
-// Purpose: update workplane by given parameters of the sketch
+// Function: updateFeature
+// Purpose: create/update constraint or feature in appropriate group
// ============================================================================
-bool SketchSolver_Manager::changeWorkplane(CompositeFeaturePtr theSketch)
+bool SketchSolver_Manager::updateFeature(const std::shared_ptr<SketchPlugin_Feature>& theFeature)
{
- bool aResult = true; // changed when a workplane wrongly updated
- bool isUpdated = false;
- // Try to update specified workplane in all groups
- std::vector<SketchSolver_Group*>::iterator aGroupIter;
- for (aGroupIter = myGroups.begin(); aGroupIter != myGroups.end(); aGroupIter++)
- if ((*aGroupIter)->isBaseWorkplane(theSketch)) {
- isUpdated = true;
- aResult = false;
- }
- // If the workplane is not updated, so this is a new workplane
- if (!isUpdated) {
- SketchSolver_Group* aNewGroup = new SketchSolver_Group(theSketch);
- // Verify that the group is created successfully
- if (!aNewGroup->isBaseWorkplane(theSketch) || !aNewGroup->isWorkplaneValid()) {
- delete aNewGroup;
- return false;
- }
- myGroups.push_back(aNewGroup);
- }
- return aResult;
+ // Check feature validity and find a group to place it.
+ // If the feature is not valid, the returned group will be empty.
+ // This will protect to deal with wrong (not fully initialized) features.
+ SketchGroupPtr aGroup = findGroup(theFeature);
+ if (!aGroup)
+ return false;
+ aGroup->blockEvents(true);
+
+ std::shared_ptr<SketchPlugin_Constraint> aConstraint =
+ std::dynamic_pointer_cast<SketchPlugin_Constraint>(theFeature);
+
+ bool isOk = false;
+ if (aConstraint)
+ isOk = aGroup->changeConstraint(aConstraint);
+ else
+ isOk = aGroup->updateFeature(theFeature);
+ return isOk;
}
// ============================================================================
-// Function: changeConstraintOrEntity
-// Purpose: create/update the constraint or the feature and place it into appropriate group
+// Function: moveFeature
+// Purpose: move given feature in appropriate group
// ============================================================================
-bool SketchSolver_Manager::changeFeature(std::shared_ptr<SketchPlugin_Feature> theFeature)
+bool SketchSolver_Manager::moveFeature(
+ const std::shared_ptr<SketchPlugin_Feature>& theMovedFeature,
+ const std::shared_ptr<GeomAPI_Pnt2d>& theFrom,
+ const std::shared_ptr<GeomAPI_Pnt2d>& theTo)
{
- // Search the groups which this feature touches
- std::set<GroupID> aGroups;
- findGroups(theFeature, aGroups);
-
- std::shared_ptr<SketchPlugin_Constraint> aConstraint =
- std::dynamic_pointer_cast<SketchPlugin_Constraint>(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;
- std::shared_ptr<ModelAPI_CompositeFeature> aWP = findWorkplane(aConstraint);
- if (!aWP)
- return false;
- SketchSolver_Group* aGroup = new SketchSolver_Group(aWP);
- if (!aGroup->changeConstraint(aConstraint)) {
- delete aGroup;
- return false;
- }
- myGroups.push_back(aGroup);
- return true;
- } else if (aGroups.size() == 1) { // Only one group => add feature into it
- GroupID aGroupId = *(aGroups.begin());
- std::vector<SketchSolver_Group*>::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)->updateFeature(theFeature);
- return (*aGroupIter)->changeConstraint(aConstraint);
- }
- } else if (aGroups.size() > 1) { // Several groups applicable for this feature => need to merge them
- std::set<GroupID>::const_iterator aGroupsIter = aGroups.begin();
-
- // Search first group
- std::vector<SketchSolver_Group*>::iterator aFirstGroupIter;
- for (aFirstGroupIter = myGroups.begin(); aFirstGroupIter != myGroups.end(); aFirstGroupIter++)
- if ((*aFirstGroupIter)->getId() == *aGroupsIter)
- break;
- if (aFirstGroupIter == myGroups.end())
- return false;
-
- // Append other groups to the first one
- std::vector<SketchSolver_Group*>::iterator anOtherGroupIter = aFirstGroupIter + 1;
- for (aGroupsIter++; aGroupsIter != aGroups.end(); aGroupsIter++) {
- for (; anOtherGroupIter != myGroups.end(); anOtherGroupIter++)
- if ((*anOtherGroupIter)->getId() == *aGroupsIter)
- break;
- if (anOtherGroupIter == myGroups.end()) { // Group disappears
- anOtherGroupIter = aFirstGroupIter + 1;
- continue;
- }
-
- (*aFirstGroupIter)->mergeGroups(**anOtherGroupIter);
- int aShiftFirst = aFirstGroupIter - myGroups.begin();
- int aShiftOther = anOtherGroupIter - myGroups.begin();
- delete *anOtherGroupIter;
- myGroups.erase(anOtherGroupIter);
- aFirstGroupIter = myGroups.begin() + aShiftFirst;
- anOtherGroupIter = myGroups.begin() + aShiftOther;
- }
-
- if (aConstraint)
- (*aFirstGroupIter)->changeConstraint(aConstraint);
- else
- (*aFirstGroupIter)->updateFeature(theFeature);
- // groups are merged => need to resolve them
+ SketchGroupPtr aGroup = findGroup(theMovedFeature);
+ if (!aGroup)
+ return false;
+
+ std::shared_ptr<SketchPlugin_Constraint> aConstraint =
+ std::dynamic_pointer_cast<SketchPlugin_Constraint>(theMovedFeature);
+ if (aConstraint)
+ {
+ std::shared_ptr<GeomDataAPI_Point2D> aPntAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>
+ (aConstraint->attribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT()));
+ aPntAttr->setValue(theTo);
+ Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
return true;
}
- // Something goes wrong
- return false;
+ aGroup->blockEvents(true);
+ return aGroup->moveFeature(theMovedFeature, theFrom, theTo);
}
// ============================================================================
-// Function: moveEntity
-// Purpose: update element moved on the sketch, which is used by constraints
+// Function: moveAttribute
+// Purpose: move given attribute in appropriate group
// ============================================================================
-void SketchSolver_Manager::moveEntity(std::shared_ptr<SketchPlugin_Feature> theFeature)
+bool SketchSolver_Manager::moveAttribute(
+ const std::shared_ptr<GeomDataAPI_Point2D>& theMovedAttribute,
+ const std::shared_ptr<GeomAPI_Pnt2d>& theFrom,
+ const std::shared_ptr<GeomAPI_Pnt2d>& theTo)
{
- std::vector<SketchSolver_Group*>::iterator aGroupIt = myGroups.begin();
- for (; aGroupIt != myGroups.end(); aGroupIt++)
- if (!(*aGroupIt)->isEmpty() && (*aGroupIt)->isInteract(theFeature))
- (*aGroupIt)->moveFeature(theFeature);
-}
+ FeaturePtr anOwner = ModelAPI_Feature::feature(theMovedAttribute->owner());
+ std::shared_ptr<SketchPlugin_Constraint> aConstraint =
+ std::dynamic_pointer_cast<SketchPlugin_Constraint>(anOwner);
+ if (aConstraint)
+ {
+ theMovedAttribute->setValue(theTo);
+ Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
+ return true;
+ }
-// ============================================================================
-// Function: findGroups
-// Purpose: search groups of entities interacting with given feature
-// ============================================================================
-void SketchSolver_Manager::findGroups(
- std::shared_ptr<SketchPlugin_Feature> theFeature,
- std::set<GroupID>& theGroupIDs) const
-{
- std::shared_ptr<ModelAPI_CompositeFeature> aWP = findWorkplane(theFeature);
-
- SketchSolver_Group* anEmptyGroup = 0; // appropriate empty group for specified constraint
- std::vector<SketchSolver_Group*>::const_iterator aGroupIter;
- for (aGroupIter = myGroups.begin(); aGroupIter != myGroups.end(); aGroupIter++)
- if (aWP == (*aGroupIter)->getWorkplane() && (*aGroupIter)->isInteract(theFeature)) {
- if (!(*aGroupIter)->isEmpty())
- theGroupIDs.insert((*aGroupIter)->getId());
- else if (!anEmptyGroup)
- anEmptyGroup = *aGroupIter;
- }
+ std::shared_ptr<SketchPlugin_Feature> aSketchFeature =
+ std::dynamic_pointer_cast<SketchPlugin_Feature>(anOwner);
+ SketchGroupPtr aGroup;
+ if (aSketchFeature)
+ aGroup = findGroup(aSketchFeature);
+ if (!aGroup) {
+ theMovedAttribute->setValue(theTo);
+ return false;
+ }
- // When only empty group is found, use it
- if (anEmptyGroup && theGroupIDs.empty())
- theGroupIDs.insert(anEmptyGroup->getId());
+ aGroup->blockEvents(true);
+ return aGroup->movePoint(theMovedAttribute, theFrom, theTo);
}
// ============================================================================
-// Function: findWorkplane
-// Purpose: search workplane containing given feature
+// Function: findGroup
+// Purpose: search groups of entities interacting with given feature
// ============================================================================
-std::shared_ptr<ModelAPI_CompositeFeature> SketchSolver_Manager
-::findWorkplane(std::shared_ptr<SketchPlugin_Feature> theFeature) const
+SketchGroupPtr SketchSolver_Manager::findGroup(
+ std::shared_ptr<SketchPlugin_Feature> theFeature)
{
- // Already verified workplanes
- std::set<std::shared_ptr<ModelAPI_CompositeFeature> > aVerified;
-
- std::vector<SketchSolver_Group*>::const_iterator aGroupIter;
- for (aGroupIter = myGroups.begin(); aGroupIter != myGroups.end(); aGroupIter++) {
- std::shared_ptr<ModelAPI_CompositeFeature> aWP = (*aGroupIter)->getWorkplane();
- if (aVerified.find(aWP) != aVerified.end())
- continue;
-
- DataPtr aData = aWP->data();
- if (aData->isValid()) {
- std::shared_ptr<ModelAPI_AttributeRefList> aWPFeatures = std::dynamic_pointer_cast<
- ModelAPI_AttributeRefList>(aData->attribute(SketchPlugin_Sketch::FEATURES_ID()));
- std::list<ObjectPtr> aFeaturesList = aWPFeatures->list();
- std::list<ObjectPtr>::const_iterator anIter;
- for (anIter = aFeaturesList.begin(); anIter != aFeaturesList.end(); anIter++)
- if (*anIter == theFeature)
- return aWP; // workplane is found
+ if (!isFeatureValid(theFeature))
+ return SketchGroupPtr(); // do not process wrong features
+
+ // Obtain sketch, containing the feature
+ CompositeFeaturePtr aSketch;
+ const std::set<AttributePtr>& aRefsList = theFeature->data()->refsToMe();
+ std::set<AttributePtr>::const_iterator aRefIt = aRefsList.begin();
+ for (; aRefIt != aRefsList.end(); ++aRefIt) {
+ FeaturePtr anOwner = ModelAPI_Feature::feature((*aRefIt)->owner());
+ if (anOwner && anOwner->getKind() == SketchPlugin_Sketch::ID()) {
+ aSketch = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(anOwner);
+ break;
}
- aVerified.insert(aWP);
}
- return std::shared_ptr<ModelAPI_CompositeFeature>();
+ if (!aSketch)
+ return SketchGroupPtr(); // not a sketch's feature
+
+ std::list<SketchGroupPtr>::const_iterator aGroupIt;
+ for (aGroupIt = myGroups.begin(); aGroupIt != myGroups.end(); ++aGroupIt)
+ if ((*aGroupIt)->getWorkplane() == aSketch)
+ return *aGroupIt;
+
+ // group for the sketch does not created yet
+ SketchGroupPtr aNewGroup = SketchGroupPtr(new SketchSolver_Group(aSketch));
+ myGroups.push_back(aNewGroup);
+ return aNewGroup;
}
// ============================================================================
bool SketchSolver_Manager::resolveConstraints()
{
bool needToUpdate = false;
- std::vector<SketchSolver_Group*>::iterator aGroupIter;
- for (aGroupIter = myGroups.begin(); aGroupIter != myGroups.end(); aGroupIter++)
+ std::list<SketchGroupPtr>::const_iterator aGroupIter = myGroups.begin();
+ for (; aGroupIter != myGroups.end(); ++aGroupIter) {
if ((*aGroupIter)->resolveConstraints())
needToUpdate = true;
+ }
return needToUpdate;
}
+void SketchSolver_Manager::releaseFeaturesIfEventsBlocked() const
+{
+ std::list<SketchGroupPtr>::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);
// 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) {
void SketchSolver_Manager::allowSendUpdate() const
{
- Events_Loop::loop()->setFlushed(anUpdateEvent, true);
+ Events_Loop::loop()->setFlushed(Events_Loop::eventByName(EVENT_OBJECT_UPDATED), true);
}