Salome HOME
SketchSolver Refactoring: Eliminate SolveSpace as a sketch solver.
[modules/shaper.git] / src / SketchSolver / SketchSolver_ConstraintFixed.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
2
3 #include <SketchSolver_ConstraintFixed.h>
4 #include <SketchSolver_Error.h>
5
6 #include <PlaneGCSSolver_ConstraintWrapper.h>
7 #include <PlaneGCSSolver_EntityWrapper.h>
8 #include <PlaneGCSSolver_PointWrapper.h>
9
10
11 SketchSolver_ConstraintFixed::SketchSolver_ConstraintFixed(ConstraintPtr theConstraint)
12   : SketchSolver_Constraint(theConstraint)
13 {
14   myType = CONSTRAINT_FIXED;
15 ////  AttributeRefAttrPtr anAttribute =
16 ////      theConstraint->refattr(SketchPlugin_ConstraintRigid::ENTITY_A());
17 ////  if (anAttribute->isObject())
18 ////    myFixedFeature = ModelAPI_Feature::feature(anAttribute->object());
19 ////  else
20 ////    myFixedAttribute = anAttribute->attr();
21 }
22
23 SketchSolver_ConstraintFixed::SketchSolver_ConstraintFixed(FeaturePtr theFeature)
24   : SketchSolver_Constraint(),
25     myBaseFeature(theFeature)
26 {
27   myType = CONSTRAINT_FIXED;
28 ////  process();
29 }
30
31 void SketchSolver_ConstraintFixed::blockEvents(bool isBlocked)
32 {
33   if (myBaseFeature)
34     myBaseFeature->data()->blockSendAttributeUpdated(isBlocked);
35   if (myBaseConstraint)
36     SketchSolver_Constraint::blockEvents(isBlocked);
37 }
38
39 void SketchSolver_ConstraintFixed::process()
40 {
41   cleanErrorMsg();
42   if ((!myBaseConstraint && !myBaseFeature) || !myStorage) {
43     // Not enough parameters are assigned
44     return;
45   }
46
47   EntityWrapperPtr aValue;
48   std::vector<EntityWrapperPtr> anEntities;
49   getAttributes(aValue, anEntities);
50   if (anEntities.empty())
51     myErrorMsg = SketchSolver_Error::ALREADY_FIXED();
52   if (!myErrorMsg.empty())
53     return;
54   fixFeature(anEntities.front());
55 }
56
57 void SketchSolver_ConstraintFixed::fixFeature(EntityWrapperPtr theFeature)
58 {
59   std::shared_ptr<PlaneGCSSolver_EntityWrapper> anEntity =
60       std::dynamic_pointer_cast<PlaneGCSSolver_EntityWrapper>(theFeature);
61
62   GCS::VEC_pD aParameters; // parameters of entity to be fixed
63
64   // Collect parameters for each type of entity
65   switch (theFeature->type()) {
66   case ENTITY_POINT: {
67     std::shared_ptr<PlaneGCSSolver_PointWrapper> aPoint =
68         std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(theFeature);
69     aParameters.push_back(aPoint->point()->x);
70     aParameters.push_back(aPoint->point()->y);
71     break;
72     }
73   case ENTITY_LINE: {
74     std::shared_ptr<GCS::Line> aLine = std::dynamic_pointer_cast<GCS::Line>(anEntity->entity());
75     aParameters.push_back(aLine->p1.x);
76     aParameters.push_back(aLine->p1.y);
77     aParameters.push_back(aLine->p2.x);
78     aParameters.push_back(aLine->p2.y);
79     break;
80     }
81   case ENTITY_CIRCLE: {
82     std::shared_ptr<GCS::Circle> aCircle =
83         std::dynamic_pointer_cast<GCS::Circle>(anEntity->entity());
84     aParameters.push_back(aCircle->center.x);
85     aParameters.push_back(aCircle->center.y);
86     aParameters.push_back(aCircle->rad);
87     break;
88     }
89   case ENTITY_ARC: {
90     myFixedValues.reserve(4);
91     std::shared_ptr<GCS::Arc> anArc = std::dynamic_pointer_cast<GCS::Arc>(anEntity->entity());
92     aParameters.push_back(anArc->center.x);
93     aParameters.push_back(anArc->center.y);
94     aParameters.push_back(anArc->rad);
95     aParameters.push_back(anArc->startAngle);
96     aParameters.push_back(anArc->endAngle);
97     break;
98     }
99   default:
100     break;
101   }
102
103   // Fix given list of parameters
104   std::list<GCSConstraintPtr> aConstraints;
105   myFixedValues.reserve(aParameters.size());
106   GCS::VEC_pD::const_iterator anIt = aParameters.begin();
107   for (int i = 0; anIt != aParameters.end(); ++anIt, ++i) {
108     myFixedValues.push_back(**anIt);
109     aConstraints.push_back(
110         GCSConstraintPtr(new GCS::ConstraintEqual(*anIt, &myFixedValues[i])));
111   }
112
113   myConstraint = ConstraintWrapperPtr(
114       new PlaneGCSSolver_ConstraintWrapper(aConstraints, getType()));
115
116   if (myBaseConstraint)
117     myStorage->addConstraint(myBaseConstraint, myConstraint);
118   else
119     myStorage->addTemporaryConstraint(myConstraint);
120 }
121
122 void SketchSolver_ConstraintFixed::getAttributes(
123     EntityWrapperPtr& theValue,
124     std::vector<EntityWrapperPtr>& theAttributes)
125 {
126   if (myBaseFeature) {
127     // The feature is fixed.
128     myStorage->update(myBaseFeature);
129     EntityWrapperPtr aSolverEntity = myStorage->entity(myBaseFeature);
130     if (aSolverEntity)
131       theAttributes.push_back(aSolverEntity);
132   } else if (myBaseConstraint) {
133     // Constraint Fixed is added by user.
134     // Get the attribute of constraint (it should be alone in the list of constraints).
135     std::vector<EntityWrapperPtr> anAttributes;
136     SketchSolver_Constraint::getAttributes(theValue, anAttributes);
137     std::vector<EntityWrapperPtr>::const_iterator anIt = anAttributes.begin();
138     for (; anIt != anAttributes.end(); ++anIt)
139       if (*anIt)
140         theAttributes.push_back(*anIt);
141   } else
142     myErrorMsg = SketchSolver_Error::NOT_INITIALIZED();
143 }