]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
PlaneGCS hangs up (issue #1183)
authorazv <azv@opencascade.com>
Fri, 15 Jan 2016 13:45:46 +0000 (16:45 +0300)
committerdbv <dbv@opencascade.com>
Tue, 16 Feb 2016 14:03:05 +0000 (17:03 +0300)
Avoid adding copied entities of MultiRotation and MultiTranslation constraints into solver to decrease number of used unknowns and constraints.

src/SketchSolver/SketchSolver_ConstraintMulti.cpp
src/SketchSolver/SketchSolver_ConstraintMulti.h
src/SketchSolver/SketchSolver_ConstraintMultiRotation.cpp
src/SketchSolver/SketchSolver_ConstraintMultiRotation.h
src/SketchSolver/SketchSolver_ConstraintMultiTranslation.cpp
src/SketchSolver/SketchSolver_ConstraintMultiTranslation.h
src/SketchSolver/SketchSolver_Manager.cpp
src/SketchSolver/SketchSolver_Manager.h

index 9db1b64e065d6505c0bb2fed7e9ef059e585974f..d2135179c35538fe52fe63c8f0c779218fafa86e 100644 (file)
@@ -2,12 +2,14 @@
 #include <SketchSolver_Error.h>
 #include <SketchSolver_Manager.h>
 
+#include <GeomDataAPI_Point2D.h>
 #include <ModelAPI_AttributeInteger.h>
 #include <ModelAPI_AttributeRefAttr.h>
 #include <ModelAPI_AttributeRefList.h>
+#include <SketchPlugin_Arc.h>
+#include <SketchPlugin_Line.h>
 
-void SketchSolver_ConstraintMulti::getEntitiesAndCopies(
-    std::list< std::list<EntityWrapperPtr> >& theEntAndCopies)
+void SketchSolver_ConstraintMulti::getEntities(std::list<EntityWrapperPtr>& theEntities)
 {
   myAdjusted = false;
   DataPtr aData = myBaseConstraint->data();
@@ -28,24 +30,20 @@ void SketchSolver_ConstraintMulti::getEntitiesAndCopies(
   }
 
   FeaturePtr aFeature;
-  std::list<EntityWrapperPtr> anEntities; // list of transformed entities
   std::list<ObjectPtr> anObjectList = aRefList->list();
   std::list<ObjectPtr>::iterator anObjIt = anObjectList.begin();
   if ((myNumberOfCopies + 1) * myNumberOfObjects != aRefList->size()) // execute for the feature is not called yet
     myNumberOfCopies = aRefList->size() / myNumberOfObjects - 1;
 
   while (anObjIt != anObjectList.end()) {
-    anEntities.clear();
-    for (int i = 0; i <= myNumberOfCopies && anObjIt != anObjectList.end(); ++i, ++anObjIt) {
-      aFeature = ModelAPI_Feature::feature(*anObjIt);
-      if (!aFeature)
-        continue;
+    aFeature = ModelAPI_Feature::feature(*anObjIt++);
+    if (!aFeature)
+      continue;
 
-      myStorage->update(aFeature);
-      anEntities.push_back(myStorage->entity(aFeature));
-    }
-    if (!anEntities.empty())
-      theEntAndCopies.push_back(anEntities);
+    myStorage->update(aFeature);
+    theEntities.push_back(myStorage->entity(aFeature));
+    for (int i = 0; i < myNumberOfCopies && anObjIt != anObjectList.end(); ++i, ++anObjIt)
+      ; // just skip copied features
   }
 }
 
@@ -77,16 +75,78 @@ void SketchSolver_ConstraintMulti::update(bool isForce)
 
 void SketchSolver_ConstraintMulti::adjustConstraint()
 {
-  if (myAdjusted)
-    return; // constraint already adjusted, don't do it once again
+  AttributeRefListPtr aRefList = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
+      myBaseConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
+  if (!aRefList || aRefList->size() == 0) {
+    myErrorMsg = SketchSolver_Error::INCORRECT_ATTRIBUTE();
+    return;
+  }
 
-  BuilderPtr aBuilder = SketchSolver_Manager::instance()->builder();
+  FeaturePtr aFeature;
+  std::list<ObjectPtr> anObjectList = aRefList->list();
+  std::list<ObjectPtr>::iterator anObjIt = anObjectList.begin();
+  while (anObjIt != anObjectList.end()) {
+    aFeature = ModelAPI_Feature::feature(*anObjIt++);
+    if (!aFeature)
+      continue;
 
-  const std::list<ConstraintWrapperPtr>& aConstraints = myStorage->constraint(myBaseConstraint);
-  std::list<ConstraintWrapperPtr>::const_iterator anIt = aConstraints.begin();
-  for (; anIt != aConstraints.end(); ++anIt)
-    aBuilder->adjustConstraint(*anIt);
-  myStorage->addConstraint(myBaseConstraint, aConstraints);
+    // Fill lists of coordinates of points composing a feature
+    std::list<double> aX, aY;
+    std::list<double>::iterator aXIt, aYIt;
+    double aXCoord, aYCoord;
+    EntityWrapperPtr anEntity = myStorage->entity(aFeature);
+    std::list<EntityWrapperPtr> aSubs = anEntity->subEntities();
+    std::list<EntityWrapperPtr>::const_iterator aSIt = aSubs.begin();
+    for (; aSIt != aSubs.end(); ++aSIt) {
+      if ((*aSIt)->type() != ENTITY_POINT)
+        continue;
+      std::list<ParameterWrapperPtr> aParameters = (*aSIt)->parameters();
+      aXCoord = aParameters.front()->value();
+      aYCoord = aParameters.back()->value();
+      getRelative(aXCoord, aYCoord, aXCoord, aYCoord);
+      aX.push_back(aXCoord);
+      aY.push_back(aYCoord);
+    }
+
+    // Calculate positions of copied features
+    for (int i = 0; i < myNumberOfCopies && anObjIt != anObjectList.end(); ++i, ++anObjIt) {
+      aFeature = ModelAPI_Feature::feature(*anObjIt);
+      if (!aFeature)
+        continue;
+      anEntity = myStorage->entity(aFeature);
+
+      if (!anEntity || !myStorage->isEventsBlocked())
+        aFeature->data()->blockSendAttributeUpdated(true);
+
+      std::list<AttributePtr> aPoints;
+      if (aFeature->getKind() == SketchPlugin_Arc::ID()) {
+        aPoints.push_back(aFeature->attribute(SketchPlugin_Arc::CENTER_ID()));
+        aPoints.push_back(aFeature->attribute(SketchPlugin_Arc::START_ID()));
+        aPoints.push_back(aFeature->attribute(SketchPlugin_Arc::END_ID()));
+      } else if (aFeature->getKind() == SketchPlugin_Line::ID()) {
+        aPoints.push_back(aFeature->attribute(SketchPlugin_Line::START_ID()));
+        aPoints.push_back(aFeature->attribute(SketchPlugin_Line::END_ID()));
+      } else
+        aPoints = aFeature->data()->attributes(GeomDataAPI_Point2D::typeId());
+
+      std::list<AttributePtr>::iterator aPtIt = aPoints.begin();
+      for (aXIt = aX.begin(), aYIt = aY.begin(); aPtIt != aPoints.end(); ++aXIt, ++aYIt, ++aPtIt) {
+        transformRelative(*aXIt, *aYIt);
+        getAbsolute(*aXIt, *aYIt, aXCoord, aYCoord);
+
+        std::shared_ptr<GeomDataAPI_Point2D> aPoint2D =
+            std::dynamic_pointer_cast<GeomDataAPI_Point2D>(*aPtIt);
+        aPoint2D->setValue(aXCoord, aYCoord);
+      }
+
+      // update feature in the storage if it is used by another constraints
+      if (anEntity)
+        myStorage->update(aFeature);
+
+      if (!anEntity || !myStorage->isEventsBlocked())
+        aFeature->data()->blockSendAttributeUpdated(false);
+    }
+  }
 
   myAdjusted = true;
 }
index 70fe5e7817ab1ee6ffc82323be267486d5eb3ab8..16db54dbde8881cb2178a782c4515850705d8621 100644 (file)
@@ -37,8 +37,8 @@ protected:
   virtual void process()
   { /* do nothing here */ }
 
-  /// \brief Collect entities and their copies, like circles and arcs
-  void getEntitiesAndCopies(std::list< std::list<EntityWrapperPtr> >& theEntAndCopies);
+  /// \brief Collect entities which translated or rotated (not their copies)
+  void getEntities(std::list<EntityWrapperPtr>& theEntities);
 
   /// \brief Generate list of attributes of constraint in order useful for SolveSpace constraints
   /// \param[out] theValue      numerical characteristic of constraint (e.g. distance)
@@ -54,6 +54,14 @@ protected:
 
   /// \brief Returns name of NUMBER_OF_COPIES parameter for corresponding feature
   virtual const std::string& nameNbObjects() = 0;
+  
+protected:
+  /// \brief Convert absolute coordinates to relative coordinates
+  virtual void getRelative(double theAbsX, double theAbsY, double& theRelX, double& theRelY) = 0;
+  /// \brief Convert relative coordinates to absolute coordinates
+  virtual void getAbsolute(double theRelX, double theRelY, double& theAbsX, double& theAbsY) = 0;
+  /// \brief Apply transformation for relative coordinates
+  virtual void transformRelative(double& theX, double& theY) = 0;
 
 protected:
   int myNumberOfObjects; ///< number of previous initial objects
index a322e66bec8ae501723350d442a40a1de66e88c0..e2839f7b9468cf07b7daa7ec303e8cb6b0582738 100644 (file)
@@ -10,8 +10,7 @@
 
 void SketchSolver_ConstraintMultiRotation::getAttributes(
     EntityWrapperPtr& theCenter, double& theAngle,
-    bool& theFullValue,
-    std::list< std::list<EntityWrapperPtr> >& theEntities)
+    bool& theFullValue, std::list<EntityWrapperPtr>& theEntities)
 {
   DataPtr aData = myBaseConstraint->data();
   theAngle = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(
@@ -31,7 +30,7 @@ void SketchSolver_ConstraintMultiRotation::getAttributes(
   AttributeStringPtr aMethodTypeAttr = aData->string(SketchPlugin_MultiRotation::ANGLE_TYPE());
   theFullValue = aMethodTypeAttr->value() != "SingleAngle";
 
-  getEntitiesAndCopies(theEntities);
+  getEntities(theEntities);
 }
 
 void SketchSolver_ConstraintMultiRotation::process()
@@ -44,19 +43,19 @@ void SketchSolver_ConstraintMultiRotation::process()
 
   EntityWrapperPtr aRotationCenter;
   bool isFullValue;
-  std::list<std::list<EntityWrapperPtr> > anEntitiesAndCopies;
-  getAttributes(aRotationCenter, myAngle, isFullValue, anEntitiesAndCopies);
+  std::list<EntityWrapperPtr> aBaseEntities;
+  getAttributes(aRotationCenter, myAngle, isFullValue, aBaseEntities);
   if (!myErrorMsg.empty())
     return;
 
   BuilderPtr aBuilder = SketchSolver_Manager::instance()->builder();
   std::list<ConstraintWrapperPtr> aRotConstraints;
 
-  std::list< std::list<EntityWrapperPtr> >::iterator anEntIt = anEntitiesAndCopies.begin();
-  for (; anEntIt != anEntitiesAndCopies.end(); ++anEntIt) {
+  std::list<EntityWrapperPtr>::iterator anEntIt = aBaseEntities.begin();
+  for (; anEntIt != aBaseEntities.end(); ++anEntIt) {
     std::list<ConstraintWrapperPtr> aNewConstraints =
         aBuilder->createConstraint(myBaseConstraint, myGroupID, mySketchID, myType,
-        myAngle, isFullValue, aRotationCenter, EntityWrapperPtr(), *anEntIt);
+        myAngle, isFullValue, aRotationCenter, EntityWrapperPtr(), std::list<EntityWrapperPtr>(1, *anEntIt));
     aRotConstraints.insert(aRotConstraints.end(), aNewConstraints.begin(), aNewConstraints.end());
   }
   myStorage->addConstraint(myBaseConstraint, aRotConstraints);
@@ -124,6 +123,9 @@ void SketchSolver_ConstraintMultiRotation::updateLocal()
 
 void SketchSolver_ConstraintMultiRotation::adjustConstraint()
 {
+  if (myAdjusted)
+    return;
+
   if (fabs(myAngle) < tolerance) {
     myStorage->setNeedToResolve(false);
     return;
@@ -134,9 +136,42 @@ void SketchSolver_ConstraintMultiRotation::adjustConstraint()
   for (; aCIt != aConstraints.end(); ++aCIt)
     (*aCIt)->setValue(myAngle);
 
+  // Obtain coordinates of rotation center
+  EntityWrapperPtr aRotCenter = myStorage->entity(
+      myBaseConstraint->attribute(SketchPlugin_MultiRotation::CENTER_ID()));
+  std::list<ParameterWrapperPtr> aParams = aRotCenter->parameters();
+  myCenterCoord[0] = aParams.front()->value();
+  myCenterCoord[1] = aParams.back()->value();
+
+  myRotationVal[0] = sin(myAngle * PI / 180.0);
+  myRotationVal[1] = cos(myAngle * PI / 180.0);
+
   SketchSolver_ConstraintMulti::adjustConstraint();
 }
 
+void SketchSolver_ConstraintMultiRotation::getRelative(
+    double theAbsX, double theAbsY, double& theRelX, double& theRelY)
+{
+  theRelX = theAbsX - myCenterCoord[0];
+  theRelY = theAbsY - myCenterCoord[1];
+}
+
+void SketchSolver_ConstraintMultiRotation::getAbsolute(
+    double theRelX, double theRelY, double& theAbsX, double& theAbsY)
+{
+  theAbsX = theRelX + myCenterCoord[0];
+  theAbsY = theRelY + myCenterCoord[1];
+}
+
+void SketchSolver_ConstraintMultiRotation::transformRelative(double& theX, double& theY)
+{
+  // rotate direction
+  // myRotationVal[0] = sinA, myRotationVal[1] = cosA
+  double aTemp = theX * myRotationVal[1] - theY * myRotationVal[0];
+  theY = theX * myRotationVal[0] + theY * myRotationVal[1];
+  theX = aTemp;
+}
+
 const std::string& SketchSolver_ConstraintMultiRotation::nameNbObjects()
 {
   return SketchPlugin_MultiRotation::NUMBER_OF_OBJECTS_ID();
index 6d241f92df261b2b2929157e667242f429b65ca6..69e792bcc47fa125313672abf71e685c5d299e3c 100644 (file)
@@ -32,9 +32,9 @@ protected:
   /// \param[out] theCenter   central point of rotation
   /// \param[out] theAngle    rotation angle
   /// \param[out] theFullValue  applying translation using the disstance as a full or single value
-  /// \param[out] theEntities list of entities and their rotated copies
+  /// \param[out] theEntities list of base entities
   void getAttributes(EntityWrapperPtr& theCenter, double& theAngle, bool& theFullValue,
-                     std::list< std::list<EntityWrapperPtr> >& theEntities);
+                     std::list<EntityWrapperPtr>& theEntities);
 
   /// \brief This method is used in derived objects to check consistence of constraint.
   virtual void adjustConstraint();
@@ -43,12 +43,23 @@ protected:
   virtual void updateLocal();
 
 private:
+  /// \brief Convert absolute coordinates to relative coordinates
+  virtual void getRelative(double theAbsX, double theAbsY, double& theRelX, double& theRelY);
+  /// \brief Convert relative coordinates to absolute coordinates
+  virtual void getAbsolute(double theRelX, double theRelY, double& theAbsX, double& theAbsY);
+  /// \brief Apply transformation for relative coordinates
+  virtual void transformRelative(double& theX, double& theY);
+
   /// \brief Returns name of NUMBER_OF_COPIES parameter for corresponding feature
   virtual const std::string& nameNbObjects();
 
+private:
   AttributePoint2DPtr myCenterPointAttribute; ///< a center of rotation
   double              myAngle;           ///< angle of rotation
   bool                myIsFullValue;     ///< value whether the angle is a full or single for objects
+
+  double myCenterCoord[2]; ///< coordinates of rotation center
+  double myRotationVal[2]; ///< sinus and cosine of rotation angle
 };
 
 #endif
index 5d0b01931248a57045811911e35efb543b0c2db9..dd740003a3654babe6ea50769994edfa856991f8 100644 (file)
@@ -10,7 +10,7 @@
 
 void SketchSolver_ConstraintMultiTranslation::getAttributes(
     EntityWrapperPtr& theStartPoint, EntityWrapperPtr& theEndPoint,
-    bool& theFullValue, std::list< std::list<EntityWrapperPtr> >& theEntities)
+    bool& theFullValue, std::list<EntityWrapperPtr>& theEntities)
 {
   DataPtr aData = myBaseConstraint->data();
   AttributePtr aStartPointAttr = aData->attribute(SketchPlugin_MultiTranslation::START_POINT_ID());
@@ -31,7 +31,7 @@ void SketchSolver_ConstraintMultiTranslation::getAttributes(
   AttributeStringPtr aMethodTypeAttr = aData->string(SketchPlugin_MultiTranslation::VALUE_TYPE());
   theFullValue = aMethodTypeAttr->value() != "SingleValue";
 
-  getEntitiesAndCopies(theEntities);
+  getEntities(theEntities);
 }
 
 void SketchSolver_ConstraintMultiTranslation::process()
@@ -44,8 +44,8 @@ void SketchSolver_ConstraintMultiTranslation::process()
 
   EntityWrapperPtr aStartPoint, aEndPoint;
   bool aFullValue;
-  std::list<std::list<EntityWrapperPtr> > anEntitiesAndCopies;
-  getAttributes(aStartPoint, aEndPoint, aFullValue, anEntitiesAndCopies);
+  std::list<EntityWrapperPtr> aBaseEntities;
+  getAttributes(aStartPoint, aEndPoint, aFullValue, aBaseEntities);
   if (!myErrorMsg.empty())
     return;
 
@@ -55,11 +55,11 @@ void SketchSolver_ConstraintMultiTranslation::process()
   BuilderPtr aBuilder = SketchSolver_Manager::instance()->builder();
   std::list<ConstraintWrapperPtr> aTransConstraints;
 
-  std::list< std::list<EntityWrapperPtr> >::iterator anEntIt = anEntitiesAndCopies.begin();
-  for (; anEntIt != anEntitiesAndCopies.end(); ++anEntIt) {
+  std::list<EntityWrapperPtr>::iterator anEntIt = aBaseEntities.begin();
+  for (; anEntIt != aBaseEntities.end(); ++anEntIt) {
     std::list<ConstraintWrapperPtr> aNewConstraints =
         aBuilder->createConstraint(myBaseConstraint, myGroupID, mySketchID, myType,
-        0.0, aFullValue, aStartPoint, aEndPoint, *anEntIt);
+        0.0, aFullValue, aStartPoint, aEndPoint, std::list<EntityWrapperPtr>(1, *anEntIt));
     aTransConstraints.insert(aTransConstraints.end(), aNewConstraints.begin(), aNewConstraints.end());
   }
 
@@ -136,3 +136,42 @@ void SketchSolver_ConstraintMultiTranslation::updateLocal()
   }
 }
 
+void SketchSolver_ConstraintMultiTranslation::adjustConstraint()
+{
+  if (myAdjusted)
+    return;
+
+  // Obtain delta between start and end points of translation
+  EntityWrapperPtr aStart = myStorage->entity(
+      myBaseConstraint->attribute(SketchPlugin_MultiTranslation::START_POINT_ID()));
+  std::list<ParameterWrapperPtr> aStartParams = aStart->parameters();
+  EntityWrapperPtr aEnd = myStorage->entity(
+      myBaseConstraint->attribute(SketchPlugin_MultiTranslation::END_POINT_ID()));
+  std::list<ParameterWrapperPtr> aEndParams = aEnd->parameters();
+  myDelta[0] = aEndParams.front()->value() - aStartParams.front()->value();
+  myDelta[1] = aEndParams.back()->value() - aStartParams.back()->value();
+
+  SketchSolver_ConstraintMulti::adjustConstraint();
+}
+
+void SketchSolver_ConstraintMultiTranslation::getRelative(
+    double theAbsX, double theAbsY, double& theRelX, double& theRelY)
+{
+  theRelX = theAbsX;
+  theRelY = theAbsY;
+}
+
+void SketchSolver_ConstraintMultiTranslation::getAbsolute(
+    double theRelX, double theRelY, double& theAbsX, double& theAbsY)
+{
+  theAbsX = theRelX;
+  theAbsY = theRelY;
+}
+
+void SketchSolver_ConstraintMultiTranslation::transformRelative(double& theX, double& theY)
+{
+  // translate coordinates
+  theX += myDelta[0];
+  theY += myDelta[1];
+}
+
index ef9938a9c12785337cd7062f05e36819e68d4647..59cb06f9342d0e00c4bad06151df5f28c30dfaf2 100644 (file)
@@ -31,15 +31,25 @@ protected:
   /// \brief Generate list of translated entities
   /// \param[out] theStartPoint start point of translation
   /// \param[out] theEndPoint   final point of translation
-  /// \param[out] theFullValue  applying translation using the disstance as a full or single value
-  /// \param[out] theEntities   list of entities and their translated copies
+  /// \param[out] theFullValue  applying translation using the distance as a full or single value
+  /// \param[out] theEntities   list of base entities
   void getAttributes(EntityWrapperPtr& theStartPoint, EntityWrapperPtr& theEndPoint,
-                     bool& theFullValue, std::list< std::list<EntityWrapperPtr> >& theEntities);
+                     bool& theFullValue, std::list<EntityWrapperPtr>& theEntities);
+
+  /// \brief This method is used in derived objects to check consistence of constraint.
+  virtual void adjustConstraint();
 
   /// \brief Update parameters (called from base class)
   virtual void updateLocal();
 
 private:
+  /// \brief Convert absolute coordinates to relative coordinates
+  virtual void getRelative(double theAbsX, double theAbsY, double& theRelX, double& theRelY);
+  /// \brief Convert relative coordinates to absolute coordinates
+  virtual void getAbsolute(double theRelX, double theRelY, double& theAbsX, double& theAbsY);
+  /// \brief Apply transformation for relative coordinates
+  virtual void transformRelative(double& theX, double& theY);
+
   /// \brief Returns name of NUMBER_OF_COPIES parameter for corresponding feature
   virtual const std::string& nameNbObjects();
 
@@ -47,6 +57,8 @@ private:
   AttributePoint2DPtr myStartPointAttribute;
   AttributePoint2DPtr myEndPointAttribute;
   bool                myIsFullValue;
+
+  double myDelta[2]; ///< increment of translation
 };
 
 #endif
index 354a3d9d8a43bd794bcd050d36e2a908145a3645..ba8b2ea17a80a839991b123ebc9dcb71655e65bb 100644 (file)
@@ -28,6 +28,8 @@
 #include <set>
 #include <memory>
 
+static const Events_ID anUpdateEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED);
+
 // Initialization of constraint manager self pointer
 SketchSolver_Manager* SketchSolver_Manager::mySelf = 0;
 
@@ -89,6 +91,7 @@ void SketchSolver_Manager::processEvent(
         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;
 
@@ -122,9 +125,18 @@ void SketchSolver_Manager::processEvent(
       }
     }
 
+    bool needToUpdate = false;
     // Solve the set of constraints
     if (hasProperFeature)
-      resolveConstraints(isMovedEvt); // send update for movement in any case
+      needToUpdate = resolveConstraints();
+
+    // 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);
+
   } else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_DELETED)) {
     std::shared_ptr<ModelAPI_ObjectDeletedMessage> aDeleteMsg =
       std::dynamic_pointer_cast<ModelAPI_ObjectDeletedMessage>(theMessage);
@@ -342,30 +354,27 @@ std::shared_ptr<ModelAPI_CompositeFeature> SketchSolver_Manager
 //  Function: resolveConstraints
 //  Purpose:  change entities according to available constraints
 // ============================================================================
-void SketchSolver_Manager::resolveConstraints(const bool theForceUpdate)
+bool SketchSolver_Manager::resolveConstraints()
 {
-  //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<SketchSolver_Group*>::iterator aGroupIter;
   for (aGroupIter = myGroups.begin(); aGroupIter != myGroups.end(); aGroupIter++)
     if ((*aGroupIter)->resolveConstraints())
       needToUpdate = true;
+  return needToUpdate;
+}
 
-  // Features may be updated => now send events, but for all changed at once
+bool SketchSolver_Manager::stopSendUpdate() const
+{
+  // 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, true);
+    Events_Loop::loop()->setFlushed(anUpdateEvent, false);
   }
-  // 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);
+  return isUpdateFlushed;
+}
+
+void SketchSolver_Manager::allowSendUpdate() const
+{
+  Events_Loop::loop()->setFlushed(anUpdateEvent, true);
 }
index 8ceddc79aaa790fa0c49a96f9ad677b47d477108..6883cd44877d27e2eded0acde185eeb3f7ecb63d 100644 (file)
@@ -83,9 +83,9 @@ protected:
   void moveEntity(std::shared_ptr<SketchPlugin_Feature> theFeature);
 
   /** \brief Goes through the list of groups and solve the constraints
-   *  \param theForceUpdate flushes the update event in any case: something changed or not
+   *  \return \c true, if groups are resolved, and features should be updated (send the Update event)
    */
-  void resolveConstraints(const bool theForceUpdate);
+  bool resolveConstraints();
 
 private:
   /** \brief Searches list of groups which interact with specified feature
@@ -102,6 +102,12 @@ private:
   std::shared_ptr<ModelAPI_CompositeFeature> findWorkplane(
       std::shared_ptr<SketchPlugin_Feature> theFeature) const;
 
+  /// \brief Stop sending the Update event until all features updated
+  /// \return \c true, if the last flushed event is Update
+  bool stopSendUpdate() const;
+  /// \brief Allow to send the Update event
+  void allowSendUpdate() const;
+
 private:
   static SketchSolver_Manager*     mySelf;    ///< Self pointer to implement singleton functionality
   std::vector<SketchSolver_Group*> myGroups;  ///< Groups of constraints