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()) {
104 void SketchSolver_ConstraintMulti::adjustConstraint()
106 AttributeRefListPtr aRefList =
107 myBaseConstraint->reflist(SketchPlugin_Constraint::ENTITY_B());
108 if (!aRefList || aRefList->size() == 0) {
109 myErrorMsg = SketchSolver_Error::INCORRECT_ATTRIBUTE();
113 FeaturePtr anOriginal, aFeature;
114 std::list<double>::iterator aXIt, aYIt;
116 std::list<ObjectPtr> anObjectList = aRefList->list();
117 std::list<ObjectPtr>::iterator anObjIt = anObjectList.begin();
118 while (anObjIt != anObjectList.end()) {
119 anOriginal = ModelAPI_Feature::feature(*anObjIt++);
123 // Fill lists of coordinates of points composing a feature
124 std::list<double> aX, aY;
125 double aXCoord, aYCoord;
126 std::list<AttributePtr> aPoints =
127 anOriginal->data()->attributes(GeomDataAPI_Point2D::typeId());
128 std::list<AttributePtr>::iterator aPtIt = aPoints.begin();
129 for (; aPtIt != aPoints.end(); ++aPtIt) {
130 AttributePoint2DPtr aPoint2D = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(*aPtIt);
131 if (aPoint2D->isInitialized()) {
132 aXCoord = aPoint2D->x();
133 aYCoord = aPoint2D->y();
134 getRelative(aXCoord, aYCoord, aXCoord, aYCoord);
136 aXCoord = aYCoord = 0;
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);
148 if (myIsEventsBlocked)
149 aFeature->data()->blockSendAttributeUpdated(true);
151 if (aFeature->getKind() == SketchPlugin_Circle::ID()) // update circle's radius
152 aFeature->real(SketchPlugin_Circle::RADIUS_ID())->setValue(
153 anOriginal->real(SketchPlugin_Circle::RADIUS_ID())->value());
155 aPoints = aFeature->data()->attributes(GeomDataAPI_Point2D::typeId());
156 for (aPtIt = aPoints.begin(), aXIt = aX.begin(), aYIt = aY.begin();
157 aPtIt != aPoints.end(); ++aXIt, ++aYIt, ++aPtIt) {
158 if (!(*aPtIt)->isInitialized())
160 transformRelative(*aXIt, *aYIt);
161 getAbsolute(*aXIt, *aYIt, aXCoord, aYCoord);
163 AttributePoint2DPtr aPoint2D =
164 std::dynamic_pointer_cast<GeomDataAPI_Point2D>(*aPtIt);
165 aPoint2D->setValue(aXCoord, aYCoord);
173 void SketchSolver_ConstraintMulti::notify(const FeaturePtr& theFeature,
174 PlaneGCSSolver_Update*)
176 if (myFeatures.find(theFeature) == myFeatures.end())
177 return; // the feature is not used by constraint => nothing to update
179 // update derivative object
185 void SketchSolver_ConstraintMulti::blockEvents(bool isBlocked)
187 myIsEventsBlocked = isBlocked;
189 std::set<FeaturePtr>::iterator anIt = myFeatures.begin();
190 for (; anIt != myFeatures.end(); ++anIt)
191 (*anIt)->data()->blockSendAttributeUpdated(isBlocked);
193 SketchSolver_Constraint::blockEvents(isBlocked);