]> SALOME platform Git repositories - modules/shaper.git/blob - src/SketchSolver/SketchSolver_ConstraintTangent.cpp
Salome HOME
Fix compilation errors (part 2)
[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 #include <SketchSolver_Manager.h>
6
7 #include <GeomAPI_Pnt2d.h>
8 #include <SketchPlugin_Circle.h>
9 #include <SketchPlugin_ConstraintCoincidence.h>
10
11 #include <cmath>
12
13
14 /// \brief Check whether the entities has only one shared point or less
15 static bool hasSingleCoincidence(FeaturePtr theFeature1, FeaturePtr theFeature2)
16 {
17   const std::set<AttributePtr>& aRefs1 = theFeature1->data()->refsToMe();
18   const std::set<AttributePtr>& aRefs2 = theFeature2->data()->refsToMe();
19
20   // collect all shared coincidendes
21   std::set<FeaturePtr> aCoincidences;
22   std::set<AttributePtr>::const_iterator anIt;
23   for (anIt = aRefs1.begin(); anIt != aRefs1.end(); ++anIt) {
24     FeaturePtr aRef = ModelAPI_Feature::feature((*anIt)->owner());
25     if (aRef && aRef->getKind() == SketchPlugin_ConstraintCoincidence::ID())
26       aCoincidences.insert(aRef);
27   }
28   for (anIt = aRefs2.begin(); anIt != aRefs2.end(); ++anIt) {
29     FeaturePtr aRef = ModelAPI_Feature::feature((*anIt)->owner());
30     if (aRef)
31       aCoincidences.erase(aRef);
32   }
33
34   return aCoincidences.size() <= 1;
35 }
36
37 /// \brief Check if two connected arcs have centers
38 ///        in same direction relatively to connection point
39 static bool isInternalTangency(EntityWrapperPtr theEntity1, EntityWrapperPtr theEntity2)
40 {
41   BuilderPtr aBuilder = SketchSolver_Manager::instance()->builder();
42   return aBuilder->isArcArcTangencyInternal(theEntity1, theEntity2);
43 }
44
45
46 void SketchSolver_ConstraintTangent::getAttributes(
47     EntityWrapperPtr& theValue,
48     std::vector<EntityWrapperPtr>& theAttributes)
49 {
50   SketchSolver_Constraint::getAttributes(theValue, theAttributes);
51   if (!myErrorMsg.empty() || !theAttributes[2] || !theAttributes[3]) {
52     theAttributes.clear();
53     return;
54   }
55
56   // Check the quantity of entities of each type and their order (arcs first)
57   int aNbLines = 0;
58   int aNbArcs = 0;
59   int aNbCircles = 0;
60   bool isSwap = false; // whether need to swap arguments (arc goes before line)
61   std::vector<EntityWrapperPtr>::iterator anEntIt = theAttributes.begin() + 2;
62   for (; anEntIt != theAttributes.end(); ++anEntIt) {
63     if ((*anEntIt)->type() == ENTITY_LINE)
64       ++aNbLines;
65     else if ((*anEntIt)->type() == ENTITY_ARC) {
66       ++aNbArcs;
67       isSwap = aNbLines > 0;
68     }
69     else if ((*anEntIt)->type() == ENTITY_CIRCLE) {
70       ++aNbCircles;
71       isSwap = aNbLines > 0;
72     }
73   }
74
75   if (aNbArcs < 1 && aNbCircles < 1) {
76     myErrorMsg = SketchSolver_Error::INCORRECT_TANGENCY_ATTRIBUTE();
77     return;
78   }
79   if (aNbLines == 1) {
80     if (aNbArcs == 1)
81       myType = CONSTRAINT_TANGENT_ARC_LINE;
82     else if (aNbCircles == 1)
83       myType = CONSTRAINT_TANGENT_CIRCLE_LINE;
84   }
85   else if (aNbArcs == 2) {
86     myType = CONSTRAINT_TANGENT_ARC_ARC;
87     isArcArcInternal = isInternalTangency(theAttributes[2], theAttributes[3]);
88   }
89   else {
90     myErrorMsg = SketchSolver_Error::INCORRECT_ATTRIBUTE();
91     return;
92   }
93
94   if (myType == CONSTRAINT_TANGENT_ARC_LINE) {
95     AttributeRefAttrPtr aRefAttr = myBaseConstraint->refattr(SketchPlugin_Constraint::ENTITY_A());
96     FeaturePtr aFeature1 = ModelAPI_Feature::feature(aRefAttr->object());
97     aRefAttr = myBaseConstraint->refattr(SketchPlugin_Constraint::ENTITY_B());
98     FeaturePtr aFeature2 = ModelAPI_Feature::feature(aRefAttr->object());
99
100     if (!hasSingleCoincidence(aFeature1, aFeature2))
101       myErrorMsg = SketchSolver_Error::TANGENCY_FAILED();
102   }
103
104   if (isSwap) {
105     EntityWrapperPtr aTemp = theAttributes[2];
106     theAttributes[2] = theAttributes[3];
107     theAttributes[3] = aTemp;
108   }
109 }
110
111 void SketchSolver_ConstraintTangent::adjustConstraint()
112 {
113   if (myType == CONSTRAINT_TANGENT_ARC_ARC) {
114     EntityWrapperPtr anEntity1 =
115         myStorage->entity(myBaseConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
116     EntityWrapperPtr anEntity2 =
117         myStorage->entity(myBaseConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
118
119     if (isArcArcInternal != isInternalTangency(anEntity1, anEntity2)) {
120       // fully rebuld constraint, because it is unable to access attributes of PlaneGCS constraint
121       remove();
122       process();
123     }
124   }
125 }