Salome HOME
First phase of SketchSolver refactoring
[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     std::shared_ptr<GeomAPI_Pnt2d> aPt1 = aBuilder->point(*anIt1);
25     for (anIt2 = aStartIt2; anIt2 != aPoints2.end(); ++anIt2) {
26       std::shared_ptr<GeomAPI_Pnt2d> aPt2 = aBuilder->point(*anIt2);
27       if (aPt1->distance(aPt2) < tolerance)
28         ++aNbCoinc;
29     }
30   }
31   return aNbCoinc == 1;
32 }
33
34
35 void SketchSolver_ConstraintTangent::getAttributes(
36     double& theValue,
37     std::vector<EntityWrapperPtr>& theAttributes)
38 {
39   SketchSolver_Constraint::getAttributes(theValue, theAttributes);
40   if (!myErrorMsg.empty() || !theAttributes[2] || !theAttributes[3]) {
41     theAttributes.clear();
42     return;
43   }
44
45   // Check the quantity of entities of each type and their order (arcs first)
46   int aNbLines = 0;
47   int aNbArcs = 0;
48   bool isSwap = false; // whether need to swap arguments (arc goes before line)
49   std::vector<EntityWrapperPtr>::iterator anEntIt = theAttributes.begin() + 2;
50   for (; anEntIt != theAttributes.end(); ++anEntIt) {
51     if ((*anEntIt)->type() == ENTITY_LINE)
52       ++aNbLines;
53     else if ((*anEntIt)->type() == ENTITY_ARC) {
54       ++aNbArcs;
55       isSwap = aNbLines > 0;
56     }
57   }
58
59   if (aNbArcs < 1) {
60     myErrorMsg = SketchSolver_Error::INCORRECT_TANGENCY_ATTRIBUTE();
61     return;
62   }
63   if (aNbLines == 1 && aNbArcs == 1)
64     myType = CONSTRAINT_TANGENT_ARC_LINE;
65   else if (aNbArcs == 2)
66     myType = CONSTRAINT_TANGENT_ARC_ARC;
67   else {
68     myErrorMsg = SketchSolver_Error::INCORRECT_ATTRIBUTE();
69     return;
70   }
71
72   if (!hasSingleCoincidence(theAttributes[2], theAttributes[3]))
73     myErrorMsg = SketchSolver_Error::INCORRECT_ATTRIBUTE();
74
75   if (isSwap) {
76     EntityWrapperPtr aTemp = theAttributes[2];
77     theAttributes[2] = theAttributes[3];
78     theAttributes[3] = aTemp;
79   }
80 }
81
82
83 ////void SketchSolver_ConstraintTangent::process()
84 ////{
85 ////  cleanErrorMsg();
86 ////  if (!myBaseConstraint || !myStorage || myGroup == 0) {
87 ////    /// TODO: Put error message here
88 ////    return;
89 ////  }
90 ////  if (!mySlvsConstraints.empty()) // some data is changed, update constraint
91 ////    update(myBaseConstraint);
92 ////
93 ////  double aValue;
94 ////  std::vector<Slvs_hEntity> anEntID;
95 ////  getAttributes(aValue, anEntID);
96 ////  if (!myErrorMsg.empty())
97 ////    return;
98 ////  // Check the quantity of entities of each type and their order (arcs first)
99 ////  int aNbLines = 0;
100 ////  int aNbArcs = 0;
101 ////  Slvs_Entity anEntities[2];
102 ////  myType = SLVS_C_CURVE_CURVE_TANGENT;
103 ////  std::vector<Slvs_hEntity>::iterator anEntIter = anEntID.begin();
104 ////  for (; anEntIter != anEntID.end(); anEntIter++) {
105 ////    Slvs_Entity anEnt = myStorage->getEntity(*anEntIter);
106 ////    if (anEnt.type == SLVS_E_LINE_SEGMENT) {
107 ////      if (aNbLines == 0)
108 ////        anEntities[1 + aNbLines] = anEnt;
109 ////      aNbLines++;
110 ////      myType = SLVS_C_ARC_LINE_TANGENT;
111 ////    }
112 ////    else if (anEnt.type == SLVS_E_ARC_OF_CIRCLE) {
113 ////      if (aNbArcs < 2)
114 ////        anEntities[aNbArcs] = anEnt;
115 ////      aNbArcs++;
116 ////    }
117 ////  }
118 ////
119 ////  if (aNbLines + aNbArcs != 2) {
120 ////    myErrorMsg = SketchSolver_Error::INCORRECT_ATTRIBUTE();
121 ////    return;
122 ////  } else if (aNbArcs < 1) {
123 ////    myErrorMsg = SketchSolver_Error::INCORRECT_TANGENCY_ATTRIBUTE();
124 ////    return;
125 ////  }
126 ////
127 ////  // It is necessary to identify which points of entities are coincident
128 ////  int aSlvsOtherFlag = 0;
129 ////  int aSlvsOther2Flag = 0;
130 ////  // Obtain start and end points of entities
131 ////  Slvs_hEntity aPointsToFind[4];
132 ////  for (int i = 0; i < 2; i++) {
133 ////    int aShift = anEntities[i].type == SLVS_E_ARC_OF_CIRCLE ? 1 : 0;
134 ////    aPointsToFind[2*i]  = anEntities[i].point[aShift];
135 ////    aPointsToFind[2*i+1]= anEntities[i].point[aShift+1];
136 ////  }
137 ////  // Search coincident points
138 ////  bool isPointFound = false;
139 ////  for (int i = 0; i < 2 && !isPointFound; i++)
140 ////    for (int j = 2; j < 4 && !isPointFound; j++)
141 ////      if (myStorage->isEqual(aPointsToFind[i], aPointsToFind[j])) {
142 ////        aSlvsOtherFlag = i;
143 ////        aSlvsOther2Flag = j - 2;
144 ////        isPointFound = true;
145 ////      }
146 ////  if (!isPointFound) {
147 ////    // There is no coincident points between tangential objects. Generate error message
148 ////    myErrorMsg = SketchSolver_Error::NO_COINCIDENT_POINTS();
149 ////    return;
150 ////  }
151 ////
152 ////  Slvs_Constraint aConstraint = Slvs_MakeConstraint(SLVS_C_UNKNOWN, myGroup->getId(),
153 ////      getType(), myGroup->getWorkplaneId(), aValue,
154 ////      SLVS_E_UNKNOWN, SLVS_E_UNKNOWN, anEntities[0].h, anEntities[1].h);
155 ////  aConstraint.other = aSlvsOtherFlag;
156 ////  aConstraint.other2 = aSlvsOther2Flag;
157 ////  aConstraint.h = myStorage->addConstraint(aConstraint);
158 ////  mySlvsConstraints.push_back(aConstraint.h);
159 ////  adjustConstraint();
160 ////}
161