1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
3 #include <SketchSolver_ConstraintMulti.h>
4 #include <SketchSolver_Error.h>
5 #include <SketchSolver_Manager.h>
7 #include <GeomDataAPI_Point2D.h>
8 #include <ModelAPI_AttributeInteger.h>
9 #include <ModelAPI_AttributeRefAttr.h>
10 #include <ModelAPI_AttributeRefList.h>
11 #include <SketchPlugin_Arc.h>
12 #include <SketchPlugin_Circle.h>
13 #include <SketchPlugin_Line.h>
14 #include <SketchPlugin_Point.h>
15 #include <SketchPlugin_IntersectionPoint.h>
17 void SketchSolver_ConstraintMulti::getEntities(std::list<EntityWrapperPtr>& theEntities)
21 // Lists of objects and number of copies
22 AttributeRefListPtr anInitialRefList =
23 myBaseConstraint->reflist(SketchPlugin_Constraint::ENTITY_A());
24 myNumberOfObjects = anInitialRefList->size();
25 myNumberOfCopies = myBaseConstraint->integer(nameNbObjects())->value() - 1;
26 if (myNumberOfCopies <= 0)
29 AttributeRefListPtr aRefList =
30 myBaseConstraint->reflist(SketchPlugin_Constraint::ENTITY_B());
31 if (!aRefList || aRefList->size() == 0) {
32 myErrorMsg = SketchSolver_Error::INCORRECT_ATTRIBUTE();
37 std::list<ObjectPtr> anObjectList = aRefList->list();
38 std::list<ObjectPtr>::iterator anObjIt = anObjectList.begin();
39 // execute for the feature is not called yet
40 if ((myNumberOfCopies + 1) * myNumberOfObjects != aRefList->size())
41 myNumberOfCopies = aRefList->size() / myNumberOfObjects - 1;
43 while (anObjIt != anObjectList.end()) {
44 aFeature = ModelAPI_Feature::feature(*anObjIt++);
48 // the entity is not created, so it is a copy in "multi" constraint, force its creation
49 if (!myStorage->update(aFeature))
50 myStorage->update(aFeature, true);
51 theEntities.push_back(myStorage->entity(aFeature));
52 myFeatures.insert(aFeature);
53 for (int i = 0; i < myNumberOfCopies && anObjIt != anObjectList.end(); ++i, ++anObjIt) {
54 // just add copied features into the list of objects
55 aFeature = ModelAPI_Feature::feature(*anObjIt);
57 myFeatures.insert(aFeature);
62 bool SketchSolver_ConstraintMulti::remove()
64 myStorage->unsubscribeUpdates(this);
67 return SketchSolver_Constraint::remove();
70 void SketchSolver_ConstraintMulti::update()
73 AttributeRefListPtr anInitialRefList =
74 myBaseConstraint->reflist(SketchPlugin_Constraint::ENTITY_A());
75 AttributeIntegerPtr aNbObjects = myBaseConstraint->integer(nameNbObjects());
76 if (!anInitialRefList || !aNbObjects)
77 return; // the "Multi" constraint is in queue to remove
79 anInitialRefList->size() != myNumberOfObjects || aNbObjects->value()-1 != myNumberOfCopies;
81 // additional check that the features and their copies are changed
82 AttributeRefListPtr aRefList =
83 myBaseConstraint->reflist(SketchPlugin_Constraint::ENTITY_B());
84 if (aRefList && aRefList->size() != 0) {
86 std::list<ObjectPtr> anObjectList = aRefList->list();
87 std::list<ObjectPtr>::iterator anObjIt = anObjectList.begin();
88 for (; anObjIt != anObjectList.end(); ++anObjIt) {
89 aFeature = ModelAPI_Feature::feature(*anObjIt);
90 if (aFeature && myFeatures.find(aFeature) == myFeatures.end()) {
103 // update derived object
108 void SketchSolver_ConstraintMulti::adjustConstraint()
110 AttributeRefListPtr aRefList =
111 myBaseConstraint->reflist(SketchPlugin_Constraint::ENTITY_B());
112 if (!aRefList || aRefList->size() == 0) {
113 myErrorMsg = SketchSolver_Error::INCORRECT_ATTRIBUTE();
117 FeaturePtr anOriginal, aFeature;
118 std::list<double>::iterator aXIt, aYIt;
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 double aXCoord, aYCoord;
130 std::list<AttributePtr> aPoints =
131 anOriginal->data()->attributes(GeomDataAPI_Point2D::typeId());
132 std::list<AttributePtr>::iterator aPtIt = aPoints.begin();
133 for (; aPtIt != aPoints.end(); ++aPtIt) {
134 AttributePoint2DPtr aPoint2D = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(*aPtIt);
135 if (aPoint2D->isInitialized()) {
136 aXCoord = aPoint2D->x();
137 aYCoord = aPoint2D->y();
138 getRelative(aXCoord, aYCoord, aXCoord, aYCoord);
140 aXCoord = aYCoord = 0;
142 aX.push_back(aXCoord);
143 aY.push_back(aYCoord);
146 // Calculate positions of copied features
147 for (int i = 0; i < myNumberOfCopies && anObjIt != anObjectList.end(); ++i, ++anObjIt) {
148 aFeature = ModelAPI_Feature::feature(*anObjIt);
152 if (myIsEventsBlocked)
153 aFeature->data()->blockSendAttributeUpdated(true);
155 if (aFeature->getKind() == SketchPlugin_Circle::ID()) // update circle's radius
156 aFeature->real(SketchPlugin_Circle::RADIUS_ID())->setValue(
157 anOriginal->real(SketchPlugin_Circle::RADIUS_ID())->value());
159 aPoints = aFeature->data()->attributes(GeomDataAPI_Point2D::typeId());
160 for (aPtIt = aPoints.begin(), aXIt = aX.begin(), aYIt = aY.begin();
161 aPtIt != aPoints.end(); ++aXIt, ++aYIt, ++aPtIt) {
162 if (!(*aPtIt)->isInitialized())
164 transformRelative(*aXIt, *aYIt);
165 getAbsolute(*aXIt, *aYIt, aXCoord, aYCoord);
167 AttributePoint2DPtr aPoint2D =
168 std::dynamic_pointer_cast<GeomDataAPI_Point2D>(*aPtIt);
169 aPoint2D->setValue(aXCoord, aYCoord);
177 void SketchSolver_ConstraintMulti::notify(const FeaturePtr& theFeature,
178 PlaneGCSSolver_Update*)
180 if (myFeatures.find(theFeature) == myFeatures.end())
181 return; // the feature is not used by constraint => nothing to update
183 // update derivative object
189 void SketchSolver_ConstraintMulti::blockEvents(bool isBlocked)
191 myIsEventsBlocked = isBlocked;
193 std::set<FeaturePtr>::iterator anIt = myFeatures.begin();
194 for (; anIt != myFeatures.end(); ++anIt)
195 (*anIt)->data()->blockSendAttributeUpdated(isBlocked);
197 SketchSolver_Constraint::blockEvents(isBlocked);