]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Fix incorrect tangency between arcs when one arc changes its direction (issue #1291)
authorazv <azv@opencascade.com>
Tue, 6 Sep 2016 15:26:14 +0000 (18:26 +0300)
committerazv <azv@opencascade.com>
Tue, 6 Sep 2016 15:28:13 +0000 (18:28 +0300)
src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Builder.cpp
src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Builder.h
src/SketchSolver/SketchSolver_Builder.h
src/SketchSolver/SketchSolver_ConstraintTangent.cpp
src/SketchSolver/SketchSolver_ConstraintTangent.h
src/SketchSolver/SketchSolver_Group.cpp

index a7c348db78a0c00b73b3ee9be87ea8a550d2c90d..fd02a9d20d5905d659227d51b722143564940da0 100644 (file)
@@ -1213,3 +1213,21 @@ void adjustMirror(ConstraintWrapperPtr theConstraint)
     (*aCIt)->rescale();
 }
 
+bool PlaneGCSSolver_Builder::isArcArcTangencyInternal(
+    EntityWrapperPtr theArc1, EntityWrapperPtr theArc2) const
+{
+  std::shared_ptr<GCS::Circle> aCirc1 = std::dynamic_pointer_cast<GCS::Circle>(
+      GCS_ENTITY_WRAPPER(theArc1)->entity());
+  std::shared_ptr<GCS::Circle> aCirc2 = std::dynamic_pointer_cast<GCS::Circle>(
+      GCS_ENTITY_WRAPPER(theArc2)->entity());
+
+  if (!aCirc1 || !aCirc2)
+    return false;
+
+  double aDX = *(aCirc1->center.x) - *(aCirc2->center.x);
+  double aDY = *(aCirc1->center.y) - *(aCirc2->center.y);
+  double aDist = sqrt(aDX * aDX + aDY * aDY);
+
+  return (aDist < *(aCirc1->rad) || aDist < *(aCirc2->rad));
+}
+
index ae534dafa682e46af3b742a462714260d1122c04..a1402237c2918e59369428827686e2abe948ee37 100644 (file)
@@ -109,6 +109,10 @@ public:
   /// \return Created wrapper for parameter
   ParameterWrapperPtr createParameter(const GroupID& theGroupID, double theValue = 0.0) const;
 
+  /// \brief Check if two connected arcs have centers
+  ///        in same direction relatively to connection point
+  virtual bool isArcArcTangencyInternal(EntityWrapperPtr theArc1, EntityWrapperPtr theArc2) const;
+
 private:
   /// \brief Create necessary constraints to make two object symmetric relatively a given line
   std::list<ConstraintWrapperPtr> createMirror(ConstraintPtr theConstraint,
index 86a395bc29a4925e818a4254747fcb622f389926..fe34cb06e59db903ac594f557d2d74603f9c6306 100644 (file)
@@ -113,6 +113,11 @@ public:
   /// \brief Convert entity to line
   /// \return empty pointer if the entity is not a line
   SKETCHSOLVER_EXPORT std::shared_ptr<GeomAPI_Lin2d> line(EntityWrapperPtr theEntity) const;
+
+  /// \brief Check if two connected arcs have centers
+  ///        in same direction relatively to connection point
+  SKETCHSOLVER_EXPORT virtual bool isArcArcTangencyInternal(EntityWrapperPtr theArc1, EntityWrapperPtr theArc2) const
+  { return false; }
 };
 
 typedef std::shared_ptr<SketchSolver_Builder> BuilderPtr;
index 299ed53fa94356949d8cf004d6be036f5f7f79f8..29744ea32e41f923479ccc57085fdf1b28763fb2 100644 (file)
@@ -38,6 +38,14 @@ static bool hasSingleCoincidence(EntityWrapperPtr theEntity1, EntityWrapperPtr t
   return aNbCoinc == 1;
 }
 
+/// \brief Check if two connected arcs have centers
+///        in same direction relatively to connection point
+static bool isInternalTangency(EntityWrapperPtr theEntity1, EntityWrapperPtr theEntity2)
+{
+  BuilderPtr aBuilder = SketchSolver_Manager::instance()->builder();
+  return aBuilder->isArcArcTangencyInternal(theEntity1, theEntity2);
+}
+
 
 void SketchSolver_ConstraintTangent::getAttributes(
     double& theValue,
@@ -78,8 +86,10 @@ void SketchSolver_ConstraintTangent::getAttributes(
     else if (aNbCircles == 1)
       myType = CONSTRAINT_TANGENT_CIRCLE_LINE;
   }
-  else if (aNbArcs == 2)
+  else if (aNbArcs == 2) {
     myType = CONSTRAINT_TANGENT_ARC_ARC;
+    isArcArcInternal = isInternalTangency(theAttributes[2], theAttributes[3]);
+  }
   else {
     myErrorMsg = SketchSolver_Error::INCORRECT_ATTRIBUTE();
     return;
@@ -98,24 +108,32 @@ void SketchSolver_ConstraintTangent::getAttributes(
 
 void SketchSolver_ConstraintTangent::adjustConstraint()
 {
-  if (myType != CONSTRAINT_TANGENT_CIRCLE_LINE)
-    return;
-
-  ConstraintWrapperPtr aConstraint = myStorage->constraint(myBaseConstraint).front();
-  AttributePtr aCircleCenter = aConstraint->entities().front()->baseAttribute();
-  if (!aCircleCenter)
-    return;
-  FeaturePtr aCircle = ModelAPI_Feature::feature(aCircleCenter->owner());
-  AttributeDoublePtr aRadius = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(
-      aCircle->attribute(SketchPlugin_Circle::RADIUS_ID()));
-
-  if (fabs(aRadius->value()) == fabs(aConstraint->value()))
-    return;
-
-  aConstraint->setValue(aRadius->value());
-
-  // Adjust the sign of constraint value
-  BuilderPtr aBuilder = SketchSolver_Manager::instance()->builder();
-  aBuilder->adjustConstraint(aConstraint);
-  myStorage->addConstraint(myBaseConstraint, aConstraint);
+  if (myType == CONSTRAINT_TANGENT_CIRCLE_LINE) {
+    ConstraintWrapperPtr aConstraint = myStorage->constraint(myBaseConstraint).front();
+    AttributePtr aCircleCenter = aConstraint->entities().front()->baseAttribute();
+    if (!aCircleCenter)
+      return;
+    FeaturePtr aCircle = ModelAPI_Feature::feature(aCircleCenter->owner());
+    AttributeDoublePtr aRadius = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(
+        aCircle->attribute(SketchPlugin_Circle::RADIUS_ID()));
+
+    if (fabs(aRadius->value()) == fabs(aConstraint->value()))
+      return;
+
+    aConstraint->setValue(aRadius->value());
+
+    // Adjust the sign of constraint value
+    BuilderPtr aBuilder = SketchSolver_Manager::instance()->builder();
+    aBuilder->adjustConstraint(aConstraint);
+    myStorage->addConstraint(myBaseConstraint, aConstraint);
+  }
+  else if (myType == CONSTRAINT_TANGENT_ARC_ARC) {
+    ConstraintWrapperPtr aConstraint = myStorage->constraint(myBaseConstraint).front();
+    if (isArcArcInternal != isInternalTangency(
+        aConstraint->entities().front(), aConstraint->entities().back())) {
+      // fully rebuld constraint, because it is unable to access attributes of PlaneGCS constraint
+      remove();
+      process();
+    }
+  }
 }
index 2ffa8de02977b700bbe887cec63c8957047b7463..589d1ab4537a365a01b66a17f3e4559a7571c38d 100644 (file)
@@ -19,7 +19,8 @@ class SketchSolver_ConstraintTangent : public SketchSolver_Constraint
 public:
   /// Constructor based on SketchPlugin constraint
   SketchSolver_ConstraintTangent(ConstraintPtr theConstraint) :
-      SketchSolver_Constraint(theConstraint)
+      SketchSolver_Constraint(theConstraint),
+      isArcArcInternal(false)
   {}
 
 protected:
@@ -31,6 +32,9 @@ protected:
   /// \brief This method is used in derived objects to check consistency of constraint.
   ///        E.g. the distance between line and point may be signed.
   virtual void adjustConstraint();
+
+private:
+  bool isArcArcInternal;
 };
 
 #endif
index 0e4211a3a15cd18f540afbe250e629fa6716dc39..5a1ff49fbc122747495399c842cf2cb7ea2c201d 100644 (file)
@@ -220,7 +220,7 @@ static void updateMultiConstraints(ConstraintConstraintMap& theConstraints, Feat
          aType == CONSTRAINT_MULTI_TRANSLATION)
         && aCIt->second->isUsed(theFeature))
       std::dynamic_pointer_cast<SketchSolver_ConstraintMulti>(aCIt->second)->update(true);
-    else if ((aType == CONSTRAINT_TANGENT_CIRCLE_LINE ||
+    else if ((aType == CONSTRAINT_TANGENT_CIRCLE_LINE || aType == CONSTRAINT_TANGENT_ARC_ARC ||
               aType == CONSTRAINT_SYMMETRIC || aType == CONSTRAINT_ANGLE)
              && aCIt->second->isUsed(theFeature))
       aCIt->second->update();