Salome HOME
PlaneGCS hangs up (issue #1183)
[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     for (int i = 0; i < myNumberOfCopies && anObjIt != anObjectList.end(); ++i, ++anObjIt)
46       ; // just skip copied features
47   }
48 }
49
50 void SketchSolver_ConstraintMulti::update()
51 {
52   update(false);
53 }
54
55
56 void SketchSolver_ConstraintMulti::update(bool isForce)
57 {
58   cleanErrorMsg();
59   AttributeRefListPtr anInitialRefList = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
60       myBaseConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
61   AttributeIntegerPtr aNbObjects = myBaseConstraint->integer(nameNbObjects());
62   if (anInitialRefList->size() != myNumberOfObjects || aNbObjects->value()-1 != myNumberOfCopies) {
63     remove();
64     process();
65     return;
66   }
67
68   // update derivative object
69   updateLocal();
70   if (isForce)
71     myAdjusted = false;
72   // update parent object
73   SketchSolver_Constraint::update();
74 }
75
76 void SketchSolver_ConstraintMulti::adjustConstraint()
77 {
78   AttributeRefListPtr aRefList = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
79       myBaseConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
80   if (!aRefList || aRefList->size() == 0) {
81     myErrorMsg = SketchSolver_Error::INCORRECT_ATTRIBUTE();
82     return;
83   }
84
85   FeaturePtr aFeature;
86   std::list<ObjectPtr> anObjectList = aRefList->list();
87   std::list<ObjectPtr>::iterator anObjIt = anObjectList.begin();
88   while (anObjIt != anObjectList.end()) {
89     aFeature = ModelAPI_Feature::feature(*anObjIt++);
90     if (!aFeature)
91       continue;
92
93     // Fill lists of coordinates of points composing a feature
94     std::list<double> aX, aY;
95     std::list<double>::iterator aXIt, aYIt;
96     double aXCoord, aYCoord;
97     EntityWrapperPtr anEntity = myStorage->entity(aFeature);
98     std::list<EntityWrapperPtr> aSubs = anEntity->subEntities();
99     std::list<EntityWrapperPtr>::const_iterator aSIt = aSubs.begin();
100     for (; aSIt != aSubs.end(); ++aSIt) {
101       if ((*aSIt)->type() != ENTITY_POINT)
102         continue;
103       std::list<ParameterWrapperPtr> aParameters = (*aSIt)->parameters();
104       aXCoord = aParameters.front()->value();
105       aYCoord = aParameters.back()->value();
106       getRelative(aXCoord, aYCoord, aXCoord, aYCoord);
107       aX.push_back(aXCoord);
108       aY.push_back(aYCoord);
109     }
110
111     // Calculate positions of copied features
112     for (int i = 0; i < myNumberOfCopies && anObjIt != anObjectList.end(); ++i, ++anObjIt) {
113       aFeature = ModelAPI_Feature::feature(*anObjIt);
114       if (!aFeature)
115         continue;
116       anEntity = myStorage->entity(aFeature);
117
118       if (!anEntity || !myStorage->isEventsBlocked())
119         aFeature->data()->blockSendAttributeUpdated(true);
120
121       std::list<AttributePtr> aPoints;
122       if (aFeature->getKind() == SketchPlugin_Arc::ID()) {
123         aPoints.push_back(aFeature->attribute(SketchPlugin_Arc::CENTER_ID()));
124         aPoints.push_back(aFeature->attribute(SketchPlugin_Arc::START_ID()));
125         aPoints.push_back(aFeature->attribute(SketchPlugin_Arc::END_ID()));
126       } else if (aFeature->getKind() == SketchPlugin_Line::ID()) {
127         aPoints.push_back(aFeature->attribute(SketchPlugin_Line::START_ID()));
128         aPoints.push_back(aFeature->attribute(SketchPlugin_Line::END_ID()));
129       } else
130         aPoints = aFeature->data()->attributes(GeomDataAPI_Point2D::typeId());
131
132       std::list<AttributePtr>::iterator aPtIt = aPoints.begin();
133       for (aXIt = aX.begin(), aYIt = aY.begin(); aPtIt != aPoints.end(); ++aXIt, ++aYIt, ++aPtIt) {
134         transformRelative(*aXIt, *aYIt);
135         getAbsolute(*aXIt, *aYIt, aXCoord, aYCoord);
136
137         std::shared_ptr<GeomDataAPI_Point2D> aPoint2D =
138             std::dynamic_pointer_cast<GeomDataAPI_Point2D>(*aPtIt);
139         aPoint2D->setValue(aXCoord, aYCoord);
140       }
141
142       // update feature in the storage if it is used by another constraints
143       if (anEntity)
144         myStorage->update(aFeature);
145
146       if (!anEntity || !myStorage->isEventsBlocked())
147         aFeature->data()->blockSendAttributeUpdated(false);
148     }
149   }
150
151   myAdjusted = true;
152 }