Salome HOME
Incorrect processing of middle point on line (issue #1511)
[modules/shaper.git] / src / SketchSolver / SketchSolver_ConstraintMiddle.cpp
1 #include <SketchSolver_ConstraintMiddle.h>
2
3 #include <SketchSolver_Builder.h>
4 #include <SketchSolver_Manager.h>
5
6 #include <GeomAPI_XY.h>
7
8 SketchSolver_ConstraintMiddle::SketchSolver_ConstraintMiddle(ConstraintPtr theConstraint)
9   : SketchSolver_Constraint(theConstraint)
10 {
11 }
12
13 void SketchSolver_ConstraintMiddle::notifyCoincidenceChanged(
14     EntityWrapperPtr theCoincAttr1,
15     EntityWrapperPtr theCoincAttr2)
16 {
17   // Check the coincidence between point and line has been changed
18   AttributePtr aPoint;
19   FeaturePtr aLine;
20   EntityWrapperPtr anEntities[2] = {theCoincAttr1, theCoincAttr2};
21   for (int i = 0; i < 2; ++i) {
22     if (anEntities[i]->type() == ENTITY_POINT)
23       aPoint = anEntities[i]->baseAttribute();
24     else if (anEntities[i]->type() == ENTITY_LINE)
25       aLine = anEntities[i]->baseFeature();
26   }
27   if (!aPoint || !aLine)
28     return;
29
30   // Check the attributes of middle-point constraint are the same point and line
31   bool isSameAttr = true;
32   for (int i = 0; i < 2 && isSameAttr; ++i) {
33     AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
34         myBaseConstraint->attribute(SketchPlugin_Constraint::ATTRIBUTE(i)));
35     if (aRefAttr->isObject()) {
36       FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttr->object());
37       isSameAttr = (aFeature == aLine);
38     } else
39       isSameAttr = (aRefAttr->attr() == aPoint);
40   }
41
42   if (isSameAttr) {
43     remove();
44     process();
45   }
46 }
47
48 void SketchSolver_ConstraintMiddle::adjustConstraint()
49 {
50   BuilderPtr aBuilder = SketchSolver_Manager::instance()->builder();
51
52   ConstraintWrapperPtr aConstraint = myStorage->constraint(myBaseConstraint).front();
53   const std::list<EntityWrapperPtr>& aSubs = aConstraint->entities();
54   std::shared_ptr<GeomAPI_Pnt2d> aMidPoint, aStart, aEnd;
55   std::list<EntityWrapperPtr>::const_iterator aSIt = aSubs.begin();
56   for (; aSIt != aSubs.end(); ++aSIt) {
57     if ((*aSIt)->type() == ENTITY_POINT)
58       aMidPoint = aBuilder->point(*aSIt);
59     else if ((*aSIt)->type() == ENTITY_LINE) {
60       const std::list<EntityWrapperPtr>& aLinePoints = (*aSIt)->subEntities();
61       aStart = aBuilder->point(aLinePoints.front());
62       aEnd = aBuilder->point(aLinePoints.back());
63     }
64   }
65
66   if (aMidPoint && aStart && aEnd) {
67     std::shared_ptr<GeomAPI_XY> aMP = aMidPoint->xy();
68     double aDot = aMP->decreased(aStart->xy())->dot(aMP->decreased(aEnd->xy()));
69     if (aDot > 0.0) {
70       aBuilder->adjustConstraint(aConstraint);
71       myStorage->addConstraint(myBaseConstraint, aConstraint);
72     }
73   }
74 }