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>
13 #include <SketchPlugin_IntersectionPoint.h>
15 void SketchSolver_ConstraintMulti::getEntities(std::list<EntityWrapperPtr>& theEntities)
18 DataPtr aData = myBaseConstraint->data();
20 // Lists of objects and number of copies
21 AttributeRefListPtr anInitialRefList = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
22 aData->attribute(SketchPlugin_Constraint::ENTITY_A()));
23 myNumberOfObjects = anInitialRefList->size();
24 myNumberOfCopies = aData->integer(nameNbObjects())->value() - 1;
25 if (myNumberOfCopies <= 0)
28 AttributeRefListPtr aRefList = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
29 aData->attribute(SketchPlugin_Constraint::ENTITY_B()));
30 if (!aRefList || aRefList->size() == 0) {
31 myErrorMsg = SketchSolver_Error::INCORRECT_ATTRIBUTE();
36 std::list<ObjectPtr> anObjectList = aRefList->list();
37 std::list<ObjectPtr>::iterator anObjIt = anObjectList.begin();
38 if ((myNumberOfCopies + 1) * myNumberOfObjects != aRefList->size()) // execute for the feature is not called yet
39 myNumberOfCopies = aRefList->size() / myNumberOfObjects - 1;
41 while (anObjIt != anObjectList.end()) {
42 aFeature = ModelAPI_Feature::feature(*anObjIt++);
46 if (!myStorage->update(aFeature)) // the entity is not created, so it is a copy in "multi" constraint, force its creation
47 myStorage->update(aFeature, myGroupID, true);
48 theEntities.push_back(myStorage->entity(aFeature));
49 myFeatures.insert(aFeature);
50 for (int i = 0; i < myNumberOfCopies && anObjIt != anObjectList.end(); ++i, ++anObjIt) {
51 // just add copied features into the list of objects
52 aFeature = ModelAPI_Feature::feature(*anObjIt);
54 myFeatures.insert(aFeature);
59 bool SketchSolver_ConstraintMulti::remove()
62 return SketchSolver_Constraint::remove();
65 void SketchSolver_ConstraintMulti::update()
70 void SketchSolver_ConstraintMulti::update(bool isForce)
73 AttributeRefListPtr anInitialRefList = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
74 myBaseConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
75 AttributeIntegerPtr aNbObjects = myBaseConstraint->integer(nameNbObjects());
76 if (!anInitialRefList || !aNbObjects)
77 return; // the "Multi" constraint is in queue to remove
78 bool isUpdated= anInitialRefList->size() != myNumberOfObjects || aNbObjects->value()-1 != myNumberOfCopies;
80 // additional check that the features and their copies are changed
81 AttributeRefListPtr aRefList = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
82 myBaseConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
83 if (aRefList && aRefList->size() != 0) {
85 std::list<ObjectPtr> anObjectList = aRefList->list();
86 std::list<ObjectPtr>::iterator anObjIt = anObjectList.begin();
87 for (; anObjIt != anObjectList.end(); ++anObjIt) {
88 aFeature = ModelAPI_Feature::feature(*anObjIt);
89 if (aFeature && myFeatures.find(aFeature) == myFeatures.end()) {
103 // update derivative object
110 void SketchSolver_ConstraintMulti::adjustConstraint()
112 AttributeRefListPtr aRefList = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
113 myBaseConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
114 if (!aRefList || aRefList->size() == 0) {
115 myErrorMsg = SketchSolver_Error::INCORRECT_ATTRIBUTE();
119 FeaturePtr anOriginal, aFeature;
120 std::list<ObjectPtr> anObjectList = aRefList->list();
121 std::list<ObjectPtr>::iterator anObjIt = anObjectList.begin();
122 while (anObjIt != anObjectList.end()) {
123 anOriginal = ModelAPI_Feature::feature(*anObjIt++);
127 // Fill lists of coordinates of points composing a feature
128 std::list<double> aX, aY;
129 std::list<double>::iterator aXIt, aYIt;
130 double aXCoord, aYCoord;
131 EntityWrapperPtr anEntity = myStorage->entity(anOriginal);
132 std::list<EntityWrapperPtr> aSubs = anEntity->subEntities();
133 std::list<EntityWrapperPtr>::const_iterator aSIt = aSubs.begin();
134 for (; aSIt != aSubs.end(); ++aSIt) {
135 if ((*aSIt)->type() != ENTITY_POINT)
137 AttributePoint2DPtr aPoint =
138 std::dynamic_pointer_cast<GeomDataAPI_Point2D>((*aSIt)->baseAttribute());
140 aXCoord = aPoint->x();
141 aYCoord = aPoint->y();
143 std::list<ParameterWrapperPtr> aParameters = (*aSIt)->parameters();
144 aXCoord = aParameters.front()->value();
145 aYCoord = aParameters.back()->value();
147 getRelative(aXCoord, aYCoord, aXCoord, aYCoord);
148 aX.push_back(aXCoord);
149 aY.push_back(aYCoord);
152 // Calculate positions of copied features
153 for (int i = 0; i < myNumberOfCopies && anObjIt != anObjectList.end(); ++i, ++anObjIt) {
154 aFeature = ModelAPI_Feature::feature(*anObjIt);
157 anEntity = myStorage->entity(aFeature);
159 if (!anEntity || !myStorage->isEventsBlocked())
160 aFeature->data()->blockSendAttributeUpdated(true);
162 std::list<AttributePtr> aPoints;
163 if (aFeature->getKind() == SketchPlugin_Arc::ID()) {
164 aPoints.push_back(aFeature->attribute(SketchPlugin_Arc::CENTER_ID()));
165 aPoints.push_back(aFeature->attribute(SketchPlugin_Arc::START_ID()));
166 aPoints.push_back(aFeature->attribute(SketchPlugin_Arc::END_ID()));
167 } else if (aFeature->getKind() == SketchPlugin_Line::ID()) {
168 aPoints.push_back(aFeature->attribute(SketchPlugin_Line::START_ID()));
169 aPoints.push_back(aFeature->attribute(SketchPlugin_Line::END_ID()));
170 } else if (aFeature->getKind() == SketchPlugin_Circle::ID()) {
171 aPoints.push_back(aFeature->attribute(SketchPlugin_Circle::CENTER_ID()));
172 // update circle's radius
173 aFeature->real(SketchPlugin_Circle::RADIUS_ID())->setValue(
174 anOriginal->real(SketchPlugin_Circle::RADIUS_ID())->value());
175 } else if (aFeature->getKind() == SketchPlugin_Point::ID() ||
176 aFeature->getKind() == SketchPlugin_IntersectionPoint::ID())
177 aPoints.push_back(aFeature->attribute(SketchPlugin_Point::COORD_ID()));
179 std::list<AttributePtr>::iterator aPtIt = aPoints.begin();
180 for (aXIt = aX.begin(), aYIt = aY.begin(); aPtIt != aPoints.end(); ++aXIt, ++aYIt, ++aPtIt) {
181 transformRelative(*aXIt, *aYIt);
182 getAbsolute(*aXIt, *aYIt, aXCoord, aYCoord);
184 std::shared_ptr<GeomDataAPI_Point2D> aPoint2D =
185 std::dynamic_pointer_cast<GeomDataAPI_Point2D>(*aPtIt);
186 aPoint2D->setValue(aXCoord, aYCoord);
189 // update feature in the storage if it is used by another constraints
191 myStorage->update(aFeature);
192 else { // update attributes, if they exist in the storage
193 for (aPtIt = aPoints.begin(); aPtIt != aPoints.end(); ++aPtIt) {
194 EntityWrapperPtr aPntEnt = myStorage->entity(*aPtIt);
196 myStorage->update(*aPtIt);
200 if (!anEntity || !myStorage->isEventsBlocked())
201 aFeature->data()->blockSendAttributeUpdated(false);
208 bool SketchSolver_ConstraintMulti::isUsed(FeaturePtr theFeature) const
210 return theFeature && (myFeatures.find(theFeature) != myFeatures.end() ||
211 SketchSolver_Constraint::isUsed(theFeature));
214 bool SketchSolver_ConstraintMulti::isUsed(AttributePtr theAttribute) const
216 AttributePtr anAttribute = theAttribute;
217 AttributeRefAttrPtr aRefAttr =
218 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(anAttribute);
220 if (aRefAttr->isObject())
221 return isUsed(ModelAPI_Feature::feature(aRefAttr->object()));
223 anAttribute = aRefAttr->attr();
228 FeaturePtr anOwner = ModelAPI_Feature::feature(anAttribute->owner());
229 return myFeatures.find(anOwner) != myFeatures.end();