Salome HOME
Simplify sketcher model. Remove obsolete files and classes.
[modules/shaper.git] / src / SketchSolver / SketchSolver_ConstraintTangent.cpp
index 299ed53fa94356949d8cf004d6be036f5f7f79f8..ab4a27ea793b8e15da0c0dbd54cbaefa7086f07c 100644 (file)
@@ -1,46 +1,42 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
 #include <SketchSolver_ConstraintTangent.h>
 #include <SketchSolver_Error.h>
-#include <SketchSolver_Manager.h>
+
+#include <PlaneGCSSolver_Tools.h>
 
 #include <GeomAPI_Pnt2d.h>
 #include <SketchPlugin_Circle.h>
+#include <SketchPlugin_ConstraintCoincidence.h>
 
 #include <cmath>
 
 
-/// \brief Check whether the entities has only one shared point
-static bool hasSingleCoincidence(EntityWrapperPtr theEntity1, EntityWrapperPtr theEntity2)
+/// \brief Check whether the entities has only one shared point or less
+static bool hasSingleCoincidence(FeaturePtr theFeature1, FeaturePtr theFeature2)
 {
-  BuilderPtr aBuilder = SketchSolver_Manager::instance()->builder();
-
-  const std::list<EntityWrapperPtr>& aPoints1 = theEntity1->subEntities();
-  const std::list<EntityWrapperPtr>& aPoints2 = theEntity2->subEntities();
-
-  std::list<EntityWrapperPtr>::const_iterator aStartIt1 = aPoints1.begin();
-  if (theEntity1->type() == ENTITY_ARC) ++aStartIt1; // skip center of arc
-  std::list<EntityWrapperPtr>::const_iterator aStartIt2 = aPoints2.begin();
-  if (theEntity2->type() == ENTITY_ARC) ++aStartIt2; // skip center of arc
-
-  int aNbCoinc = 0;
-  std::list<EntityWrapperPtr>::const_iterator anIt1, anIt2;
-  for (anIt1 = aStartIt1; anIt1 != aPoints1.end(); ++anIt1) {
-    if ((*anIt1)->type() != ENTITY_POINT)
-      continue;
-    std::shared_ptr<GeomAPI_Pnt2d> aPt1 = aBuilder->point(*anIt1);
-    for (anIt2 = aStartIt2; anIt2 != aPoints2.end(); ++anIt2) {
-      if ((*anIt2)->type() != ENTITY_POINT)
-        continue;
-      std::shared_ptr<GeomAPI_Pnt2d> aPt2 = aBuilder->point(*anIt2);
-      if (aPt1->distance(aPt2) < tolerance)
-        ++aNbCoinc;
-    }
+  const std::set<AttributePtr>& aRefs1 = theFeature1->data()->refsToMe();
+  const std::set<AttributePtr>& aRefs2 = theFeature2->data()->refsToMe();
+
+  // collect all shared coincidendes
+  std::set<FeaturePtr> aCoincidences;
+  std::set<AttributePtr>::const_iterator anIt;
+  for (anIt = aRefs1.begin(); anIt != aRefs1.end(); ++anIt) {
+    FeaturePtr aRef = ModelAPI_Feature::feature((*anIt)->owner());
+    if (aRef && aRef->getKind() == SketchPlugin_ConstraintCoincidence::ID())
+      aCoincidences.insert(aRef);
+  }
+  for (anIt = aRefs2.begin(); anIt != aRefs2.end(); ++anIt) {
+    FeaturePtr aRef = ModelAPI_Feature::feature((*anIt)->owner());
+    if (aRef)
+      aCoincidences.erase(aRef);
   }
-  return aNbCoinc == 1;
-}
 
+  return aCoincidences.size() <= 1;
+}
 
 void SketchSolver_ConstraintTangent::getAttributes(
-    double& theValue,
+    EntityWrapperPtr& theValue,
     std::vector<EntityWrapperPtr>& theAttributes)
 {
   SketchSolver_Constraint::getAttributes(theValue, theAttributes);
@@ -78,16 +74,25 @@ 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 =
+        PlaneGCSSolver_Tools::isArcArcTangencyInternal(theAttributes[2], theAttributes[3]);
+  }
   else {
     myErrorMsg = SketchSolver_Error::INCORRECT_ATTRIBUTE();
     return;
   }
 
-  if (myType == CONSTRAINT_TANGENT_ARC_LINE && 
-      !hasSingleCoincidence(theAttributes[2], theAttributes[3]))
-    myErrorMsg = SketchSolver_Error::TANGENCY_FAILED();
+  if (myType == CONSTRAINT_TANGENT_ARC_LINE) {
+    AttributeRefAttrPtr aRefAttr = myBaseConstraint->refattr(SketchPlugin_Constraint::ENTITY_A());
+    FeaturePtr aFeature1 = ModelAPI_Feature::feature(aRefAttr->object());
+    aRefAttr = myBaseConstraint->refattr(SketchPlugin_Constraint::ENTITY_B());
+    FeaturePtr aFeature2 = ModelAPI_Feature::feature(aRefAttr->object());
+
+    if (!hasSingleCoincidence(aFeature1, aFeature2))
+      myErrorMsg = SketchSolver_Error::TANGENCY_FAILED();
+  }
 
   if (isSwap) {
     EntityWrapperPtr aTemp = theAttributes[2];
@@ -98,24 +103,16 @@ 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_ARC_ARC) {
+    EntityWrapperPtr anEntity1 =
+        myStorage->entity(myBaseConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
+    EntityWrapperPtr anEntity2 =
+        myStorage->entity(myBaseConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
+
+    if (isArcArcInternal != PlaneGCSSolver_Tools::isArcArcTangencyInternal(anEntity1, anEntity2)) {
+      // fully rebuld constraint, because it is unable to access attributes of PlaneGCS constraint
+      remove();
+      process();
+    }
+  }
 }