Salome HOME
Minor updates in SketchSolver plugin
[modules/shaper.git] / src / SketchSolver / SketchSolver_ConstraintTangent.cpp
1 #include <SketchSolver_ConstraintTangent.h>
2 #include <SketchSolver_Error.h>
3 #include <SketchSolver_Manager.h>
4
5 #include <GeomAPI_Pnt2d.h>
6
7
8 /// \brief Check whether the entities has only one shared point
9 static bool hasSingleCoincidence(EntityWrapperPtr theEntity1, EntityWrapperPtr theEntity2)
10 {
11   BuilderPtr aBuilder = SketchSolver_Manager::instance()->builder();
12
13   const std::list<EntityWrapperPtr>& aPoints1 = theEntity1->subEntities();
14   const std::list<EntityWrapperPtr>& aPoints2 = theEntity2->subEntities();
15
16   std::list<EntityWrapperPtr>::const_iterator aStartIt1 = aPoints1.begin();
17   if (theEntity1->type() == ENTITY_ARC) ++aStartIt1; // skip center of arc
18   std::list<EntityWrapperPtr>::const_iterator aStartIt2 = aPoints2.begin();
19   if (theEntity2->type() == ENTITY_ARC) ++aStartIt2; // skip center of arc
20
21   int aNbCoinc = 0;
22   std::list<EntityWrapperPtr>::const_iterator anIt1, anIt2;
23   for (anIt1 = aStartIt1; anIt1 != aPoints1.end(); ++anIt1) {
24     if ((*anIt1)->type() != ENTITY_POINT)
25       continue;
26     std::shared_ptr<GeomAPI_Pnt2d> aPt1 = aBuilder->point(*anIt1);
27     for (anIt2 = aStartIt2; anIt2 != aPoints2.end(); ++anIt2) {
28       if ((*anIt2)->type() != ENTITY_POINT)
29         continue;
30       std::shared_ptr<GeomAPI_Pnt2d> aPt2 = aBuilder->point(*anIt2);
31       if (aPt1->distance(aPt2) < tolerance)
32         ++aNbCoinc;
33     }
34   }
35   return aNbCoinc == 1;
36 }
37
38
39 void SketchSolver_ConstraintTangent::getAttributes(
40     double& theValue,
41     std::vector<EntityWrapperPtr>& theAttributes)
42 {
43   SketchSolver_Constraint::getAttributes(theValue, theAttributes);
44   if (!myErrorMsg.empty() || !theAttributes[2] || !theAttributes[3]) {
45     theAttributes.clear();
46     return;
47   }
48
49   // Check the quantity of entities of each type and their order (arcs first)
50   int aNbLines = 0;
51   int aNbArcs = 0;
52   bool isSwap = false; // whether need to swap arguments (arc goes before line)
53   std::vector<EntityWrapperPtr>::iterator anEntIt = theAttributes.begin() + 2;
54   for (; anEntIt != theAttributes.end(); ++anEntIt) {
55     if ((*anEntIt)->type() == ENTITY_LINE)
56       ++aNbLines;
57     else if ((*anEntIt)->type() == ENTITY_ARC) {
58       ++aNbArcs;
59       isSwap = aNbLines > 0;
60     }
61   }
62
63   if (aNbArcs < 1) {
64     myErrorMsg = SketchSolver_Error::INCORRECT_TANGENCY_ATTRIBUTE();
65     return;
66   }
67   if (aNbLines == 1 && aNbArcs == 1)
68     myType = CONSTRAINT_TANGENT_ARC_LINE;
69   else if (aNbArcs == 2)
70     myType = CONSTRAINT_TANGENT_ARC_ARC;
71   else {
72     myErrorMsg = SketchSolver_Error::INCORRECT_ATTRIBUTE();
73     return;
74   }
75
76   if (!hasSingleCoincidence(theAttributes[2], theAttributes[3]))
77     myErrorMsg = SketchSolver_Error::INCORRECT_ATTRIBUTE();
78
79   if (isSwap) {
80     EntityWrapperPtr aTemp = theAttributes[2];
81     theAttributes[2] = theAttributes[3];
82     theAttributes[3] = aTemp;
83   }
84 }