Salome HOME
Update sketcher unit tests for code coverage
[modules/shaper.git] / src / SketchSolver / SketchSolver_ConstraintMulti.cpp
1 #include <SketchSolver_ConstraintMulti.h>
2 #include <SketchSolver_Error.h>
3 #include <SketchSolver_Manager.h>
4
5 #include <GeomDataAPI_Point2D.h>
6 #include <ModelAPI_AttributeInteger.h>
7 #include <ModelAPI_AttributeRefAttr.h>
8 #include <ModelAPI_AttributeRefList.h>
9 #include <SketchPlugin_Arc.h>
10 #include <SketchPlugin_Line.h>
11
12 void SketchSolver_ConstraintMulti::getEntities(std::list<EntityWrapperPtr>& theEntities)
13 {
14   myAdjusted = false;
15   DataPtr aData = myBaseConstraint->data();
16
17   // Lists of objects and number of copies
18   AttributeRefListPtr anInitialRefList = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
19       aData->attribute(SketchPlugin_Constraint::ENTITY_A()));
20   myNumberOfObjects = anInitialRefList->size();
21   myNumberOfCopies = aData->integer(nameNbObjects())->value() - 1;
22   if (myNumberOfCopies <= 0)
23     return;
24
25   AttributeRefListPtr aRefList = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
26       aData->attribute(SketchPlugin_Constraint::ENTITY_B()));
27   if (!aRefList || aRefList->size() == 0) {
28     myErrorMsg = SketchSolver_Error::INCORRECT_ATTRIBUTE();
29     return;
30   }
31
32   FeaturePtr aFeature;
33   std::list<ObjectPtr> anObjectList = aRefList->list();
34   std::list<ObjectPtr>::iterator anObjIt = anObjectList.begin();
35   if ((myNumberOfCopies + 1) * myNumberOfObjects != aRefList->size()) // execute for the feature is not called yet
36     myNumberOfCopies = aRefList->size() / myNumberOfObjects - 1;
37
38   while (anObjIt != anObjectList.end()) {
39     aFeature = ModelAPI_Feature::feature(*anObjIt++);
40     if (!aFeature)
41       continue;
42
43     myStorage->update(aFeature);
44     theEntities.push_back(myStorage->entity(aFeature));
45     myFeatures.insert(aFeature);
46     for (int i = 0; i < myNumberOfCopies && anObjIt != anObjectList.end(); ++i, ++anObjIt) {
47       // just add copied features into the list of objects
48       aFeature = ModelAPI_Feature::feature(*anObjIt);
49       if (aFeature)
50         myFeatures.insert(aFeature);
51     }
52   }
53 }
54
55 bool SketchSolver_ConstraintMulti::remove()
56 {
57   myFeatures.clear();
58   return SketchSolver_Constraint::remove();
59 }
60
61 void SketchSolver_ConstraintMulti::update()
62 {
63   update(false);
64 }
65
66 void SketchSolver_ConstraintMulti::update(bool isForce)
67 {
68   cleanErrorMsg();
69   AttributeRefListPtr anInitialRefList = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
70       myBaseConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
71   AttributeIntegerPtr aNbObjects = myBaseConstraint->integer(nameNbObjects());
72   bool isUpdated= anInitialRefList->size() != myNumberOfObjects || aNbObjects->value()-1 != myNumberOfCopies;
73   if (!isUpdated) {
74     // additional check that the features and their copies are changed
75     AttributeRefListPtr aRefList = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
76         myBaseConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
77     if (aRefList && aRefList->size() != 0) {
78       FeaturePtr aFeature;
79       std::list<ObjectPtr> anObjectList = aRefList->list();
80       std::list<ObjectPtr>::iterator anObjIt = anObjectList.begin();
81       for (; anObjIt != anObjectList.end(); ++anObjIt) {
82         aFeature = ModelAPI_Feature::feature(*anObjIt);
83         if (aFeature && myFeatures.find(aFeature) == myFeatures.end()) {
84           isUpdated = true;
85           break;
86         }
87       }
88     } else
89       isUpdated = true;
90   }
91   if (isUpdated) {
92     remove();
93     process();
94     return;
95   }
96
97   // update derivative object
98   updateLocal();
99   if (isForce)
100     myAdjusted = false;
101   // update parent object
102   SketchSolver_Constraint::update();
103 }
104
105 void SketchSolver_ConstraintMulti::adjustConstraint()
106 {
107   AttributeRefListPtr aRefList = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
108       myBaseConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
109   if (!aRefList || aRefList->size() == 0) {
110     myErrorMsg = SketchSolver_Error::INCORRECT_ATTRIBUTE();
111     return;
112   }
113
114   FeaturePtr aFeature;
115   std::list<ObjectPtr> anObjectList = aRefList->list();
116   std::list<ObjectPtr>::iterator anObjIt = anObjectList.begin();
117   while (anObjIt != anObjectList.end()) {
118     aFeature = ModelAPI_Feature::feature(*anObjIt++);
119     if (!aFeature)
120       continue;
121
122     // Fill lists of coordinates of points composing a feature
123     std::list<double> aX, aY;
124     std::list<double>::iterator aXIt, aYIt;
125     double aXCoord, aYCoord;
126     EntityWrapperPtr anEntity = myStorage->entity(aFeature);
127     std::list<EntityWrapperPtr> aSubs = anEntity->subEntities();
128     std::list<EntityWrapperPtr>::const_iterator aSIt = aSubs.begin();
129     for (; aSIt != aSubs.end(); ++aSIt) {
130       if ((*aSIt)->type() != ENTITY_POINT)
131         continue;
132       std::list<ParameterWrapperPtr> aParameters = (*aSIt)->parameters();
133       aXCoord = aParameters.front()->value();
134       aYCoord = aParameters.back()->value();
135       getRelative(aXCoord, aYCoord, aXCoord, aYCoord);
136       aX.push_back(aXCoord);
137       aY.push_back(aYCoord);
138     }
139
140     // Calculate positions of copied features
141     for (int i = 0; i < myNumberOfCopies && anObjIt != anObjectList.end(); ++i, ++anObjIt) {
142       aFeature = ModelAPI_Feature::feature(*anObjIt);
143       if (!aFeature)
144         continue;
145       anEntity = myStorage->entity(aFeature);
146
147       if (!anEntity || !myStorage->isEventsBlocked())
148         aFeature->data()->blockSendAttributeUpdated(true);
149
150       std::list<AttributePtr> aPoints;
151       if (aFeature->getKind() == SketchPlugin_Arc::ID()) {
152         aPoints.push_back(aFeature->attribute(SketchPlugin_Arc::CENTER_ID()));
153         aPoints.push_back(aFeature->attribute(SketchPlugin_Arc::START_ID()));
154         aPoints.push_back(aFeature->attribute(SketchPlugin_Arc::END_ID()));
155       } else if (aFeature->getKind() == SketchPlugin_Line::ID()) {
156         aPoints.push_back(aFeature->attribute(SketchPlugin_Line::START_ID()));
157         aPoints.push_back(aFeature->attribute(SketchPlugin_Line::END_ID()));
158       } else
159         aPoints = aFeature->data()->attributes(GeomDataAPI_Point2D::typeId());
160
161       std::list<AttributePtr>::iterator aPtIt = aPoints.begin();
162       for (aXIt = aX.begin(), aYIt = aY.begin(); aPtIt != aPoints.end(); ++aXIt, ++aYIt, ++aPtIt) {
163         transformRelative(*aXIt, *aYIt);
164         getAbsolute(*aXIt, *aYIt, aXCoord, aYCoord);
165
166         std::shared_ptr<GeomDataAPI_Point2D> aPoint2D =
167             std::dynamic_pointer_cast<GeomDataAPI_Point2D>(*aPtIt);
168         aPoint2D->setValue(aXCoord, aYCoord);
169       }
170
171       // update feature in the storage if it is used by another constraints
172       if (anEntity)
173         myStorage->update(aFeature);
174
175       if (!anEntity || !myStorage->isEventsBlocked())
176         aFeature->data()->blockSendAttributeUpdated(false);
177     }
178   }
179
180   myAdjusted = true;
181 }