Salome HOME
Simplify sketcher model. Remove obsolete files and classes.
[modules/shaper.git] / src / SketchSolver / SketchSolver_ConstraintTangent.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
2
3 #include <SketchSolver_ConstraintTangent.h>
4 #include <SketchSolver_Error.h>
5
6 #include <PlaneGCSSolver_Tools.h>
7
8 #include <GeomAPI_Pnt2d.h>
9 #include <SketchPlugin_Circle.h>
10 #include <SketchPlugin_ConstraintCoincidence.h>
11
12 #include <cmath>
13
14
15 /// \brief Check whether the entities has only one shared point or less
16 static bool hasSingleCoincidence(FeaturePtr theFeature1, FeaturePtr theFeature2)
17 {
18   const std::set<AttributePtr>& aRefs1 = theFeature1->data()->refsToMe();
19   const std::set<AttributePtr>& aRefs2 = theFeature2->data()->refsToMe();
20
21   // collect all shared coincidendes
22   std::set<FeaturePtr> aCoincidences;
23   std::set<AttributePtr>::const_iterator anIt;
24   for (anIt = aRefs1.begin(); anIt != aRefs1.end(); ++anIt) {
25     FeaturePtr aRef = ModelAPI_Feature::feature((*anIt)->owner());
26     if (aRef && aRef->getKind() == SketchPlugin_ConstraintCoincidence::ID())
27       aCoincidences.insert(aRef);
28   }
29   for (anIt = aRefs2.begin(); anIt != aRefs2.end(); ++anIt) {
30     FeaturePtr aRef = ModelAPI_Feature::feature((*anIt)->owner());
31     if (aRef)
32       aCoincidences.erase(aRef);
33   }
34
35   return aCoincidences.size() <= 1;
36 }
37
38 void SketchSolver_ConstraintTangent::getAttributes(
39     EntityWrapperPtr& theValue,
40     std::vector<EntityWrapperPtr>& theAttributes)
41 {
42   SketchSolver_Constraint::getAttributes(theValue, theAttributes);
43   if (!myErrorMsg.empty() || !theAttributes[2] || !theAttributes[3]) {
44     theAttributes.clear();
45     return;
46   }
47
48   // Check the quantity of entities of each type and their order (arcs first)
49   int aNbLines = 0;
50   int aNbArcs = 0;
51   int aNbCircles = 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     else if ((*anEntIt)->type() == ENTITY_CIRCLE) {
62       ++aNbCircles;
63       isSwap = aNbLines > 0;
64     }
65   }
66
67   if (aNbArcs < 1 && aNbCircles < 1) {
68     myErrorMsg = SketchSolver_Error::INCORRECT_TANGENCY_ATTRIBUTE();
69     return;
70   }
71   if (aNbLines == 1) {
72     if (aNbArcs == 1)
73       myType = CONSTRAINT_TANGENT_ARC_LINE;
74     else if (aNbCircles == 1)
75       myType = CONSTRAINT_TANGENT_CIRCLE_LINE;
76   }
77   else if (aNbArcs == 2) {
78     myType = CONSTRAINT_TANGENT_ARC_ARC;
79     isArcArcInternal =
80         PlaneGCSSolver_Tools::isArcArcTangencyInternal(theAttributes[2], theAttributes[3]);
81   }
82   else {
83     myErrorMsg = SketchSolver_Error::INCORRECT_ATTRIBUTE();
84     return;
85   }
86
87   if (myType == CONSTRAINT_TANGENT_ARC_LINE) {
88     AttributeRefAttrPtr aRefAttr = myBaseConstraint->refattr(SketchPlugin_Constraint::ENTITY_A());
89     FeaturePtr aFeature1 = ModelAPI_Feature::feature(aRefAttr->object());
90     aRefAttr = myBaseConstraint->refattr(SketchPlugin_Constraint::ENTITY_B());
91     FeaturePtr aFeature2 = ModelAPI_Feature::feature(aRefAttr->object());
92
93     if (!hasSingleCoincidence(aFeature1, aFeature2))
94       myErrorMsg = SketchSolver_Error::TANGENCY_FAILED();
95   }
96
97   if (isSwap) {
98     EntityWrapperPtr aTemp = theAttributes[2];
99     theAttributes[2] = theAttributes[3];
100     theAttributes[3] = aTemp;
101   }
102 }
103
104 void SketchSolver_ConstraintTangent::adjustConstraint()
105 {
106   if (myType == CONSTRAINT_TANGENT_ARC_ARC) {
107     EntityWrapperPtr anEntity1 =
108         myStorage->entity(myBaseConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
109     EntityWrapperPtr anEntity2 =
110         myStorage->entity(myBaseConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
111
112     if (isArcArcInternal != PlaneGCSSolver_Tools::isArcArcTangencyInternal(anEntity1, anEntity2)) {
113       // fully rebuld constraint, because it is unable to access attributes of PlaneGCS constraint
114       remove();
115       process();
116     }
117   }
118 }