1 #include <SketchSolver_ConstraintMulti.h>
2 #include <SketchSolver_Error.h>
3 #include <SketchSolver_Manager.h>
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_Circle.h>
11 #include <SketchPlugin_Line.h>
12 #include <SketchPlugin_Point.h>
14 void SketchSolver_ConstraintMulti::getEntities(std::list<EntityWrapperPtr>& theEntities)
17 DataPtr aData = myBaseConstraint->data();
19 // Lists of objects and number of copies
20 AttributeRefListPtr anInitialRefList = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
21 aData->attribute(SketchPlugin_Constraint::ENTITY_A()));
22 myNumberOfObjects = anInitialRefList->size();
23 myNumberOfCopies = aData->integer(nameNbObjects())->value() - 1;
24 if (myNumberOfCopies <= 0)
27 AttributeRefListPtr aRefList = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
28 aData->attribute(SketchPlugin_Constraint::ENTITY_B()));
29 if (!aRefList || aRefList->size() == 0) {
30 myErrorMsg = SketchSolver_Error::INCORRECT_ATTRIBUTE();
35 std::list<ObjectPtr> anObjectList = aRefList->list();
36 std::list<ObjectPtr>::iterator anObjIt = anObjectList.begin();
37 if ((myNumberOfCopies + 1) * myNumberOfObjects != aRefList->size()) // execute for the feature is not called yet
38 myNumberOfCopies = aRefList->size() / myNumberOfObjects - 1;
40 while (anObjIt != anObjectList.end()) {
41 aFeature = ModelAPI_Feature::feature(*anObjIt++);
45 myStorage->update(aFeature);
46 theEntities.push_back(myStorage->entity(aFeature));
47 myFeatures.insert(aFeature);
48 for (int i = 0; i < myNumberOfCopies && anObjIt != anObjectList.end(); ++i, ++anObjIt) {
49 // just add copied features into the list of objects
50 aFeature = ModelAPI_Feature::feature(*anObjIt);
52 myFeatures.insert(aFeature);
57 bool SketchSolver_ConstraintMulti::remove()
60 return SketchSolver_Constraint::remove();
63 void SketchSolver_ConstraintMulti::update()
68 void SketchSolver_ConstraintMulti::update(bool isForce)
71 AttributeRefListPtr anInitialRefList = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
72 myBaseConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
73 AttributeIntegerPtr aNbObjects = myBaseConstraint->integer(nameNbObjects());
74 bool isUpdated= anInitialRefList->size() != myNumberOfObjects || aNbObjects->value()-1 != myNumberOfCopies;
76 // additional check that the features and their copies are changed
77 AttributeRefListPtr aRefList = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
78 myBaseConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
79 if (aRefList && aRefList->size() != 0) {
81 std::list<ObjectPtr> anObjectList = aRefList->list();
82 std::list<ObjectPtr>::iterator anObjIt = anObjectList.begin();
83 for (; anObjIt != anObjectList.end(); ++anObjIt) {
84 aFeature = ModelAPI_Feature::feature(*anObjIt);
85 if (aFeature && myFeatures.find(aFeature) == myFeatures.end()) {
99 // update derivative object
103 // update parent object
104 SketchSolver_Constraint::update();
107 void SketchSolver_ConstraintMulti::adjustConstraint()
109 AttributeRefListPtr aRefList = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
110 myBaseConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
111 if (!aRefList || aRefList->size() == 0) {
112 myErrorMsg = SketchSolver_Error::INCORRECT_ATTRIBUTE();
117 std::list<ObjectPtr> anObjectList = aRefList->list();
118 std::list<ObjectPtr>::iterator anObjIt = anObjectList.begin();
119 while (anObjIt != anObjectList.end()) {
120 aFeature = ModelAPI_Feature::feature(*anObjIt++);
124 // Fill lists of coordinates of points composing a feature
125 std::list<double> aX, aY;
126 std::list<double>::iterator aXIt, aYIt;
127 double aXCoord, aYCoord;
128 EntityWrapperPtr anEntity = myStorage->entity(aFeature);
129 std::list<EntityWrapperPtr> aSubs = anEntity->subEntities();
130 std::list<EntityWrapperPtr>::const_iterator aSIt = aSubs.begin();
131 for (; aSIt != aSubs.end(); ++aSIt) {
132 if ((*aSIt)->type() != ENTITY_POINT)
134 std::list<ParameterWrapperPtr> aParameters = (*aSIt)->parameters();
135 aXCoord = aParameters.front()->value();
136 aYCoord = aParameters.back()->value();
137 getRelative(aXCoord, aYCoord, aXCoord, aYCoord);
138 aX.push_back(aXCoord);
139 aY.push_back(aYCoord);
142 // Calculate positions of copied features
143 for (int i = 0; i < myNumberOfCopies && anObjIt != anObjectList.end(); ++i, ++anObjIt) {
144 aFeature = ModelAPI_Feature::feature(*anObjIt);
147 anEntity = myStorage->entity(aFeature);
149 if (!anEntity || !myStorage->isEventsBlocked())
150 aFeature->data()->blockSendAttributeUpdated(true);
152 std::list<AttributePtr> aPoints;
153 if (aFeature->getKind() == SketchPlugin_Arc::ID()) {
154 aPoints.push_back(aFeature->attribute(SketchPlugin_Arc::CENTER_ID()));
155 aPoints.push_back(aFeature->attribute(SketchPlugin_Arc::START_ID()));
156 aPoints.push_back(aFeature->attribute(SketchPlugin_Arc::END_ID()));
157 } else if (aFeature->getKind() == SketchPlugin_Line::ID()) {
158 aPoints.push_back(aFeature->attribute(SketchPlugin_Line::START_ID()));
159 aPoints.push_back(aFeature->attribute(SketchPlugin_Line::END_ID()));
160 } else if (aFeature->getKind() == SketchPlugin_Circle::ID())
161 aPoints.push_back(aFeature->attribute(SketchPlugin_Circle::CENTER_ID()));
162 else if (aFeature->getKind() == SketchPlugin_Point::ID())
163 aPoints.push_back(aFeature->attribute(SketchPlugin_Point::COORD_ID()));
165 std::list<AttributePtr>::iterator aPtIt = aPoints.begin();
166 for (aXIt = aX.begin(), aYIt = aY.begin(); aPtIt != aPoints.end(); ++aXIt, ++aYIt, ++aPtIt) {
167 transformRelative(*aXIt, *aYIt);
168 getAbsolute(*aXIt, *aYIt, aXCoord, aYCoord);
170 std::shared_ptr<GeomDataAPI_Point2D> aPoint2D =
171 std::dynamic_pointer_cast<GeomDataAPI_Point2D>(*aPtIt);
172 aPoint2D->setValue(aXCoord, aYCoord);
175 // update feature in the storage if it is used by another constraints
177 myStorage->update(aFeature);
179 if (!anEntity || !myStorage->isEventsBlocked())
180 aFeature->data()->blockSendAttributeUpdated(false);