Salome HOME
Change behavior of the point-line distance constraint (in solver connector)
authorazv <azv@opencascade.com>
Tue, 4 Jun 2019 13:13:32 +0000 (16:13 +0300)
committerazv <azv@opencascade.com>
Tue, 4 Jun 2019 13:13:32 +0000 (16:13 +0300)
src/SketchPlugin/SketchPlugin_Sketch.cpp
src/SketchSolver/SketchSolver_ConstraintDistance.cpp
src/SketchSolver/SketchSolver_ConstraintDistance.h
src/SketchSolver/SketchSolver_Group.cpp
src/SketchSolver/SketchSolver_Group.h
src/SketchSolver/SketchSolver_Manager.cpp
src/SketchSolver/SketchSolver_Manager.h

index 16527cefe449b4060e2fedfdea98d6c3d94658b3..2f51ae2da3a07731069f59eb9d846f0d344798a8 100644 (file)
@@ -402,7 +402,8 @@ bool SketchPlugin_Sketch::removeLinksToExternal()
       aRemove.push_back(aFeature);
     }
     else {
-      AttributeSelectionPtr anExtAttr = aFeature->selection(SketchPlugin_SketchEntity::EXTERNAL_ID());
+      AttributeSelectionPtr anExtAttr =
+          aFeature->selection(SketchPlugin_SketchEntity::EXTERNAL_ID());
       ResultPtr anExternal = anExtAttr ? anExtAttr->context() : ResultPtr();
       if (anExternal) {
         FeaturePtr anExtFeature = ModelAPI_Feature::feature(anExternal);
@@ -421,6 +422,7 @@ bool SketchPlugin_Sketch::removeLinksToExternal()
                 SketchPlugin_IntersectionPoint::INCLUDE_INTO_RESULT())->value();
           }
 
+          aFeature->boolean(SketchPlugin_SketchEntity::COPY_ID())->setValue(false);
           aFeature->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID())->setValue(
               !isIncludedToSketchResult);
         }
@@ -428,6 +430,6 @@ bool SketchPlugin_Sketch::removeLinksToExternal()
     }
   }
   for (std::list<FeaturePtr>::iterator anIt = aRemove.begin(); anIt != aRemove.end(); ++anIt)
-    removeFeature(*anIt);
+    document()->removeFeature(*anIt);
   return true;
 }
index c3828b79405be5ae32b083a47f5a975fe0b2722b..0850933a000bdfb5e2847c328412462f2e5c2c2b 100644 (file)
@@ -95,6 +95,8 @@ void SketchSolver_ConstraintDistance::getAttributes(
     theAttributes.clear();
 
   myPrevValue = 0.0;
+
+  myStorage->subscribeUpdates(this, PlaneGCSSolver_UpdateFeature::GROUP());
 }
 
 void SketchSolver_ConstraintDistance::adjustConstraint()
@@ -209,3 +211,15 @@ void SketchSolver_ConstraintDistance::removeConstraintsKeepingSign()
 
   myIsSigned = false;
 }
+
+void SketchSolver_ConstraintDistance::notify(const FeaturePtr& theFeature,
+                                             PlaneGCSSolver_Update*)
+{
+  if (getType() == CONSTRAINT_PT_LINE_DISTANCE && myIsSigned &&
+      theFeature->getKind() == SketchPlugin_Sketch::ID()) {
+    // the sketch plane was updated, recalculate auxiliary constraints
+    removeConstraintsKeepingSign();
+    addConstraintsToKeepSign();
+    myIsSigned = true; // reset it, due to changing by removeConstraintsKeepingSign()
+  }
+}
index 7ea85d213850278e0c33cdffe7738a2b45b10c99..be316f89de5e9ae3ee75c8d7ec267355e6e70ff1 100644 (file)
@@ -42,6 +42,9 @@ public:
   /// \brief Remove constraint
   virtual bool remove();
 
+  /// \brief Notify this object about the feature is changed somewhere
+  virtual void notify(const FeaturePtr& theFeature, PlaneGCSSolver_Update*);
+
 protected:
   /// \brief Generate list of attributes of constraint in order useful for constraints
   /// \param[out] theValue      numerical characteristic of constraint (e.g. distance)
index 6e2e4ed6e83a57a4f4571abacc19fc38679d7228..637719d26f79ca030183584674800684dffa40b6 100644 (file)
@@ -73,14 +73,14 @@ static void sendMessage(const char* theMessageName,
 // ========================================================
 
 SketchSolver_Group::SketchSolver_Group(const CompositeFeaturePtr& theWorkplane)
-  : mySketch(theWorkplane),
-    myPrevResult(PlaneGCSSolver_Solver::STATUS_UNKNOWN),
+  : myPrevResult(PlaneGCSSolver_Solver::STATUS_UNKNOWN),
     myDOF(-1),
     myIsEventsBlocked(false),
     myMultiConstraintUpdateStack(0)
 {
   mySketchSolver = SolverPtr(new PlaneGCSSolver_Solver);
   myStorage = StoragePtr(new PlaneGCSSolver_Storage(mySketchSolver));
+  updateSketch(theWorkplane);
 }
 
 SketchSolver_Group::~SketchSolver_Group()
@@ -123,6 +123,34 @@ bool SketchSolver_Group::changeConstraint(
   return true;
 }
 
+bool SketchSolver_Group::updateSketch(CompositeFeaturePtr theSketch)
+{
+  static const double THE_TOLERANCE = 1.e-7;
+  bool isChanged = theSketch != mySketch;
+
+  AttributePointPtr anOrigin = std::dynamic_pointer_cast<GeomDataAPI_Point>(
+      theSketch->attribute(SketchPlugin_Sketch::ORIGIN_ID()));
+  AttributeDirPtr aNorm = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
+      theSketch->attribute(SketchPlugin_Sketch::NORM_ID()));
+  AttributeDirPtr aDirX = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
+      theSketch->attribute(SketchPlugin_Sketch::DIRX_ID()));
+
+  isChanged = isChanged
+      || (mySketchOrigin && anOrigin->pnt()->distance(mySketchOrigin) > THE_TOLERANCE)
+      || (mySketchNormal && aNorm->xyz()->distance(mySketchNormal->xyz()) > THE_TOLERANCE)
+      || (mySketchXDir && aDirX->xyz()->distance(mySketchXDir->xyz()) > THE_TOLERANCE);
+
+  if (isChanged) {
+    mySketch = theSketch;
+    mySketchOrigin = anOrigin->pnt();
+    mySketchNormal = aNorm->dir();
+    mySketchXDir = aDirX->dir();
+
+    myStorage->notify(theSketch);
+  }
+  return true;
+}
+
 bool SketchSolver_Group::updateFeature(FeaturePtr theFeature)
 {
   return myStorage->update(theFeature);
index 69ea919dc45e93f368d671fcec63c9d523554451..ed938f5d0c45f9c9749cf88d06a04650f49457f3 100644 (file)
@@ -30,6 +30,8 @@
 #include <memory>
 #include <map>
 
+class GeomAPI_Dir;
+class GeomAPI_Pnt;
 class GeomAPI_Pnt2d;
 
 typedef std::map<ConstraintPtr, SolverConstraintPtr> ConstraintConstraintMap;
@@ -67,6 +69,10 @@ class SketchSolver_Group
    */
   bool changeConstraint(std::shared_ptr<SketchPlugin_Constraint> theConstraint);
 
+  /** \brief Updates the sketch feature
+   */
+  bool updateSketch(CompositeFeaturePtr theSketch);
+
   /** \brief Updates the data corresponding the specified feature
    *  \param[in] theFeature the feature to be updated
    */
@@ -132,6 +138,10 @@ private:
 
 private:
   CompositeFeaturePtr mySketch; ///< Sketch for this group
+  std::shared_ptr<GeomAPI_Pnt> mySketchOrigin;
+  std::shared_ptr<GeomAPI_Dir> mySketchNormal;
+  std::shared_ptr<GeomAPI_Dir> mySketchXDir;
+
   ConstraintConstraintMap myConstraints; ///< List of constraints
   std::set<SolverConstraintPtr> myTempConstraints; ///< List of temporary constraints
 
index f1347a622b1a2c799d1cea45fc284713ad17d856..b4c6765d5c391f082e6882cb6295e22c1beffd82 100644 (file)
@@ -58,7 +58,8 @@ static void featuresOrderedByCreation(const std::set<ObjectPtr>& theOriginalFeat
 }
 
 static void featuresOrderedByType(const std::set<ObjectPtr>& theOriginalFeatures,
-                                  IndexedFeatureMap& theOrderedFeatures)
+                                  IndexedFeatureMap& theOrderedFeatures,
+                                  CompositeFeaturePtr& theSketch)
 {
   int aFeatureIndex = 0;
   int aConstraintIndex = (int)theOriginalFeatures.size();
@@ -67,13 +68,21 @@ static void featuresOrderedByType(const std::set<ObjectPtr>& theOriginalFeatures
   for (; aFeatIter != theOriginalFeatures.end(); aFeatIter++) {
     std::shared_ptr<SketchPlugin_Feature> aFeature =
         std::dynamic_pointer_cast<SketchPlugin_Feature>(*aFeatIter);
-    if (aFeature && !aFeature->isMacro() && aFeature->data() && aFeature->data()->isValid()) {
-      std::shared_ptr<SketchPlugin_Constraint> aConstraint =
-          std::dynamic_pointer_cast<SketchPlugin_Constraint>(aFeature);
-      if (aConstraint)
-        theOrderedFeatures[++aConstraintIndex] = aFeature;
-      else
-        theOrderedFeatures[++aFeatureIndex] = aFeature;
+    if (aFeature) {
+      if (!aFeature->isMacro() && aFeature->data() && aFeature->data()->isValid()) {
+        std::shared_ptr<SketchPlugin_Constraint> aConstraint =
+            std::dynamic_pointer_cast<SketchPlugin_Constraint>(aFeature);
+        if (aConstraint)
+          theOrderedFeatures[++aConstraintIndex] = aFeature;
+        else
+          theOrderedFeatures[++aFeatureIndex] = aFeature;
+      }
+    }
+    else {
+      std::shared_ptr<SketchPlugin_Sketch> aSketch =
+          std::dynamic_pointer_cast<SketchPlugin_Sketch>(*aFeatIter);
+      if (aSketch)
+        theSketch = aSketch;
     }
   }
 }
@@ -151,17 +160,19 @@ void SketchSolver_Manager::processEvent(
     // update sketch features only
     const std::set<ObjectPtr>& 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);
+      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<ModelAPI_ObjectMovedMessage> aMoveMsg =
@@ -228,6 +239,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<SketchGroupPtr>::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
index c80f0fc7f0210a7fef83863aa214a476c118f61d..ce83c3d9b9355c01143917f250c8c47e0200b1aa 100644 (file)
@@ -29,6 +29,7 @@
 
 class GeomAPI_Pnt2d;
 class GeomDataAPI_Point2D;
+class ModelAPI_CompositeFeature;
 class SketchPlugin_Constraint;
 
 /** \class   SketchSolver_Manager
@@ -67,6 +68,12 @@ protected:
    */
   bool updateFeature(const std::shared_ptr<SketchPlugin_Feature>& theFeature);
 
+  /** \brief Updates the sketch and related constraints, if the sketch plane is changed
+   *  \param[in] theSketch sketch to be updated
+   *  \return \c true if the sketch plane is changed
+   */
+  bool updateSketch(const std::shared_ptr<ModelAPI_CompositeFeature>& theSketch);
+
   /** \brief Move feature
    *  \param[in] theMovedFeature dragged sketch feature
    *  \param[in] theFromPoint    original position of the feature