1 #include <SketchSolver_ConstraintMulti.h>
2 #include <SketchSolver_Error.h>
3 #include <SketchSolver_Manager.h>
5 ////#include <SketchPlugin_Arc.h>
7 ////#include <ModelAPI_AttributeDouble.h>
8 #include <ModelAPI_AttributeInteger.h>
9 #include <ModelAPI_AttributeRefAttr.h>
10 #include <ModelAPI_AttributeRefList.h>
11 ////#include <ModelAPI_ResultConstruction.h>
13 ////#include <GeomAPI_Dir2d.h>
14 ////#include <GeomAPI_XY.h>
18 void SketchSolver_ConstraintMulti::getEntitiesAndCopies(
19 std::list< std::list<EntityWrapperPtr> >& theEntAndCopies)
21 DataPtr aData = myBaseConstraint->data();
23 // Lists of objects and number of copies
24 AttributeRefListPtr anInitialRefList = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
25 aData->attribute(SketchPlugin_Constraint::ENTITY_A()));
26 myNumberOfObjects = anInitialRefList->size();
27 myNumberOfCopies = aData->integer(nameNbObjects())->value() - 1;
28 if (myNumberOfCopies <= 0)
31 AttributeRefListPtr aRefList = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
32 aData->attribute(SketchPlugin_Constraint::ENTITY_B()));
33 if (!aRefList || aRefList->size() == 0) {
34 myErrorMsg = SketchSolver_Error::INCORRECT_ATTRIBUTE();
39 std::list<EntityWrapperPtr> anEntities; // list of transformed entities
40 std::list<ObjectPtr> anObjectList = aRefList->list();
41 std::list<ObjectPtr>::iterator anObjIt = anObjectList.begin();
42 while (anObjIt != anObjectList.end()) {
44 for (int i = 0; i <= myNumberOfCopies && anObjIt != anObjectList.end(); ++i, ++anObjIt) {
45 aFeature = ModelAPI_Feature::feature(*anObjIt);
49 myStorage->update(aFeature);
50 anEntities.push_back(myStorage->entity(aFeature));
52 if (!anEntities.empty())
53 theEntAndCopies.push_back(anEntities);
58 ////void SketchSolver_ConstraintMulti::processEntities(const std::vector< std::vector<Slvs_hEntity> >& theEntAndCopies)
60 //// // Keep all objects unchanged (only initial object may be changed by user)
61 //// myCircsAndCopies.clear();
62 //// std::vector<std::vector<Slvs_hEntity> >::const_iterator anEntIt = theEntAndCopies.begin();
63 //// std::vector<Slvs_hEntity>::const_iterator aCpIt;
64 //// for (; anEntIt != theEntAndCopies.end(); ++anEntIt) {
65 //// std::vector<Slvs_hEntity> aCircs;
66 //// aCpIt = anEntIt->begin();
67 //// // Obtain initial points
68 //// Slvs_Entity anInitial = myStorage->getEntity(*aCpIt);
69 //// if (anInitial.type == SLVS_E_POINT_IN_2D || anInitial.type == SLVS_E_POINT_IN_3D)
70 //// myInitialPoints.insert(anInitial.h);
72 //// for (int i = 0; i < 4 && anInitial.point[i] != SLVS_E_UNKNOWN; i++)
73 //// myInitialPoints.insert(anInitial.point[i]);
76 //// // Fix the copies
77 //// for (++aCpIt; aCpIt != anEntIt->end(); ++aCpIt) {
78 //// const Slvs_Entity& anEntity = myStorage->getEntity(*aCpIt);
79 //// std::vector<Slvs_hConstraint> aNewConstr;
80 //// if (anEntity.type == SLVS_E_CIRCLE) {
81 //// aCircs.push_back(anEntity.distance);
82 //// // for circles we fix only center
83 //// aNewConstr = myStorage->fixEntity(anEntity.point[0]);
85 //// aNewConstr = myStorage->fixEntity(*aCpIt);
86 //// if (anEntity.type == SLVS_E_ARC_OF_CIRCLE)
87 //// aCircs.push_back(anEntity.h);
88 //// mySlvsConstraints.insert(mySlvsConstraints.end(), aNewConstr.begin(), aNewConstr.end());
91 //// if (!aCircs.empty()) {
92 //// if (anInitial.type == SLVS_E_CIRCLE)
93 //// aCircs.insert(aCircs.begin(), anInitial.distance);
95 //// aCircs.insert(aCircs.begin(), anInitial.h);
96 //// myCircsAndCopies.push_back(aCircs);
101 void SketchSolver_ConstraintMulti::update(bool isForce)
104 AttributeRefListPtr anInitialRefList = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
105 myBaseConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
106 AttributeIntegerPtr aNbObjects = myBaseConstraint->integer(nameNbObjects());
107 if (anInitialRefList->size() != myNumberOfObjects || aNbObjects->value()-1 != myNumberOfCopies) {
113 // update derivative object
117 // update parent object
118 SketchSolver_Constraint::update();
121 ////bool SketchSolver_ConstraintMulti::remove()
123 //// cleanErrorMsg();
124 //// if (theConstraint && theConstraint != myBaseConstraint)
126 //// bool isFullyRemoved = true;
127 //// std::vector<Slvs_hEntity>::iterator aCIter = mySlvsConstraints.begin();
128 //// for (; aCIter != mySlvsConstraints.end(); aCIter++)
129 //// isFullyRemoved = myStorage->removeConstraint(*aCIter) && isFullyRemoved;
130 //// mySlvsConstraints.clear();
132 //// std::map<FeaturePtr, Slvs_hEntity>::iterator aFeatIt = myFeatureMap.begin();
133 //// for (; aFeatIt != myFeatureMap.end(); aFeatIt++)
134 //// myStorage->removeEntity(aFeatIt->second);
135 //// myStorage->removeUnusedEntities();
137 //// std::map<FeaturePtr, Slvs_hEntity> aFeatureMapCopy = myFeatureMap;
139 //// if (isFullyRemoved) {
140 //// myFeatureMap.clear();
141 //// myAttributeMap.clear();
142 //// myValueMap.clear();
144 //// cleanRemovedEntities();
146 //// // Restore initial features
147 //// std::map<FeaturePtr, Slvs_hEntity>::iterator aFIter = aFeatureMapCopy.begin();
148 //// for (; aFIter != aFeatureMapCopy.end(); ++aFIter)
150 //// if (myFeatureMap.find(aFIter->first) != myFeatureMap.end())
151 //// continue; // the feature was not removed
152 //// Slvs_hEntity anEntity = myGroup->getFeatureId(aFIter->first);
153 //// if (anEntity != SLVS_E_UNKNOWN)
154 //// myFeatureMap[aFIter->first] = anEntity;
157 //// // Clear list of rotated points
158 //// myPointsAndCopies.clear();
159 //// myInitialPoints.clear();
164 ////void SketchSolver_ConstraintMulti::addFeature(FeaturePtr theFeature)
166 //// SketchSolver_Constraint::addFeature(theFeature);
168 //// std::map<FeaturePtr, Slvs_hEntity>::iterator aFeatIt = myFeatureMap.find(theFeature);
169 //// if (aFeatIt == myFeatureMap.end())
172 //// // store list of points of the feature
173 //// const Slvs_Entity& theEntity = myStorage->getEntity(aFeatIt->second);
174 //// for (int i = 0; i < 4; i++)
175 //// if (theEntity.point[i] != SLVS_E_UNKNOWN)
176 //// myPointsJustUpdated.insert(theEntity.point[i]);
179 void SketchSolver_ConstraintMulti::adjustConstraint()
182 return; // constraint already adjusted, don't do it once again
184 BuilderPtr aBuilder = SketchSolver_Manager::instance()->builder();
186 const std::list<ConstraintWrapperPtr>& aConstraints = myStorage->constraint(myBaseConstraint);
187 std::list<ConstraintWrapperPtr>::const_iterator anIt = aConstraints.begin();
188 for (; anIt != aConstraints.end(); ++anIt)
189 aBuilder->adjustConstraint(*anIt);
190 myStorage->addConstraint(myBaseConstraint, aConstraints);
192 //// double aRelCoord[2] = {0.0, 0.0}; // relative coordinates of point
193 //// double anAbsCoord[2] = {0.0, 0.0}; // absolute coordinates of point
195 //// std::list<Slvs_Constraint> aCoincident = myStorage->getConstraintsByType(SLVS_C_POINTS_COINCIDENT);
196 //// std::list<Slvs_Constraint>::const_iterator aCoIt;
198 //// // Update positions of all points to satisfy angles
199 //// std::vector< std::vector<Slvs_hEntity> >::const_iterator aPointsIter = myPointsAndCopies.begin();
200 //// std::vector<Slvs_hEntity>::const_iterator aCopyIter;
201 //// for (; aPointsIter != myPointsAndCopies.end(); ++aPointsIter) {
202 //// aCopyIter = aPointsIter->begin();
203 //// const Slvs_Entity& anInitial = myStorage->getEntity(*aCopyIter);
204 //// for (int i = 0; i < 2; i++)
205 //// anAbsCoord[i] = myStorage->getParameter(anInitial.param[i]).val;
206 //// getRelative(anAbsCoord[0], anAbsCoord[1], aRelCoord[0], aRelCoord[1]);
208 //// // if the point is coincident with another one which is temporary fixed (moved by user),
209 //// // we will update its position correspondingly
210 //// Slvs_hConstraint aFixed;
211 //// for (aCoIt = aCoincident.begin(); aCoIt != aCoincident.end(); ++aCoIt) {
212 //// if ((aCoIt->ptA == anInitial.h && myInitialPoints.find(aCoIt->ptB) != myInitialPoints.end()) ||
213 //// (aCoIt->ptB == anInitial.h && myInitialPoints.find(aCoIt->ptA) != myInitialPoints.end())) {
214 //// Slvs_hEntity anOtherId = aCoIt->ptA == anInitial.h ? aCoIt->ptB : aCoIt->ptA;
215 //// if (!myStorage->isTemporary(aFixed) &&
216 //// myPointsJustUpdated.find(anOtherId) == myPointsJustUpdated.end())
217 //// continue; // nothing to change
219 //// const Slvs_Entity& anOtherPnt = myStorage->getEntity(anOtherId);
220 //// for (int i = 0; i < 2; i++) {
221 //// Slvs_Param anInitParam = myStorage->getParameter(anInitial.param[i]);
222 //// const Slvs_Param& anOtherParam = myStorage->getParameter(anOtherPnt.param[i]);
223 //// anInitParam.val = anOtherParam.val;
224 //// myStorage->updateParameter(anInitParam);
225 //// anAbsCoord[i] = anOtherParam.val;
227 //// getRelative(anAbsCoord[0], anAbsCoord[1], aRelCoord[0], aRelCoord[1]);
231 //// // update copied points
232 //// aCopyIter = aPointsIter->begin();
233 //// for (++aCopyIter; aCopyIter != aPointsIter->end(); ++aCopyIter) {
234 //// // transform coordinates
235 //// transformRelative(aRelCoord[0], aRelCoord[1]);
236 //// getAbsolute(aRelCoord[0], aRelCoord[1], anAbsCoord[0], anAbsCoord[1]);
238 //// const Slvs_Entity& aTarget = myStorage->getEntity(*aCopyIter);
239 //// for (int i = 0; i < 2; i++) {
240 //// Slvs_Param aParam = myStorage->getParameter(aTarget.param[i]);
241 //// aParam.val = anAbsCoord[i];
242 //// myStorage->updateParameter(aParam);
247 //// std::list<Slvs_Constraint> aDiamConstr;
248 //// for (aPointsIter = myCircsAndCopies.begin(); aPointsIter != myCircsAndCopies.end(); ++aPointsIter) {
249 //// aCopyIter = aPointsIter->begin();
250 //// const Slvs_Entity& anInitial = myStorage->getEntity(*aCopyIter);
251 //// if (anInitial.type == SLVS_E_DISTANCE) {
252 //// const Slvs_Param& anInitRad = myStorage->getParameter(anInitial.param[0]);
253 //// for (++aCopyIter; aCopyIter != aPointsIter->end(); ++aCopyIter) {
254 //// const Slvs_Entity& aCopy = myStorage->getEntity(*aCopyIter);
255 //// Slvs_Param aCopyRad = myStorage->getParameter(aCopy.param[0]);
256 //// aCopyRad.val = anInitRad.val;
257 //// myStorage->updateParameter(aCopyRad);
259 //// } else if (anInitial.type == SLVS_E_ARC_OF_CIRCLE) {
260 //// const Slvs_Entity& aCenterEnt = myStorage->getEntity(anInitial.point[0]);
261 //// const Slvs_Entity& aStartEnt = myStorage->getEntity(anInitial.point[1]);
263 //// if (aDiamConstr.empty())
264 //// aDiamConstr = myStorage->getConstraintsByType(SLVS_C_DIAMETER);
265 //// // Calculate diameter of initial arc
266 //// double aDiam = 0.0;
267 //// for (int i = 0; i < 2; i++) {
268 //// double d = myStorage->getParameter(aStartEnt.param[i]).val -
269 //// myStorage->getParameter(aCenterEnt.param[i]).val;
272 //// aDiam = sqrt(aDiam) * 2.0;
273 //// // Update the Diameter constraints of copied arcs
274 //// for (++aCopyIter; aCopyIter != aPointsIter->end(); ++aCopyIter) {
275 //// std::list<Slvs_Constraint>::iterator aDCIt = aDiamConstr.begin();
276 //// for (; aDCIt != aDiamConstr.end(); ++aDCIt)
277 //// if (aDCIt->entityA == *aCopyIter) {
278 //// aDCIt->valA = aDiam;
279 //// myStorage->updateConstraint(*aDCIt);
280 //// aDiamConstr.erase(aDCIt);
287 //// myPointsJustUpdated.clear();
291 ////void SketchSolver_ConstraintMulti::checkCoincidence()
293 //// std::vector< std::vector<Slvs_hEntity> > aFilteredPoints; // points are filtered by their positions
295 //// std::vector< std::vector<Slvs_hEntity> >::const_iterator aPCIt = myPointsAndCopies.begin();
296 //// std::vector<Slvs_hEntity>::const_iterator aCIt;
297 //// for (; aPCIt != myPointsAndCopies.end(); ++aPCIt) {
298 //// aCIt = aPCIt->begin();
299 //// // Skip first element, focus the copies only
300 //// for (++aCIt; aCIt != aPCIt->end(); ++aCIt) {
301 //// std::vector< std::vector<Slvs_hEntity> >::iterator aFilterIt = aFilteredPoints.begin();
302 //// for (; aFilterIt != aFilteredPoints.end(); ++aFilterIt)
303 //// if (myStorage->isEqual(*aCIt, aFilterIt->front())) {
304 //// aFilterIt->push_back(*aCIt);
307 //// if (aFilterIt == aFilteredPoints.end()) {
308 //// std::vector<Slvs_hEntity> aNewFilter(1, *aCIt);
309 //// aFilteredPoints.push_back(aNewFilter);
314 //// // Check the coicidence of filtered points and remove extra fixation.
315 //// // Also check separated points which are not fixed.
316 //// std::vector< std::vector<Slvs_hEntity> >::iterator aFPIt = aFilteredPoints.begin();
317 //// for (; aFPIt != aFilteredPoints.end(); ++aFPIt) {
318 //// if (aFPIt->size() <= 1)
320 //// std::vector<Slvs_hEntity>::iterator anIt1, anIt2;
321 //// for (anIt1 = aFPIt->begin(); anIt1 != aFPIt->end(); ++anIt1) {
322 //// for (anIt2 = anIt1 + 1; anIt2 != aFPIt->end(); ++anIt2) {
323 //// Slvs_hConstraint aFixed1, aFixed2;
324 //// bool isFixed1 = myStorage->isPointFixed(*anIt1, aFixed1);
325 //// bool isFixed2 = myStorage->isPointFixed(*anIt2, aFixed2);
326 //// if (myStorage->isCoincident(*anIt1, *anIt2)) {
327 //// if (!isFixed1 && isFixed2) {
328 //// Slvs_hEntity aTmp = *anIt1;
329 //// *anIt1 = *anIt2;
331 //// } else if (isFixed1 && isFixed2) {
332 //// // remove fixing of the second point
333 //// myStorage->removeConstraint(aFixed2);
334 //// std::vector<Slvs_hConstraint>::iterator aRemoveIt = mySlvsConstraints.begin();
335 //// for (; aRemoveIt != mySlvsConstraints.end(); ++aRemoveIt)
336 //// if (*aRemoveIt == aFixed2) {
337 //// mySlvsConstraints.erase(aRemoveIt);
342 //// bool isFixed[2] = {
343 //// myStorage->isPointFixed(*anIt1, aFixed1, true),
344 //// myStorage->isPointFixed(*anIt2, aFixed2, true)
347 //// Slvs_hEntity aPoint[2] = {*anIt1, *anIt2};
348 //// for (int i = 0; i < 2; i++)
349 //// if (!isFixed[i]) {
350 //// Slvs_Constraint aConstraint = Slvs_MakeConstraint(SLVS_C_UNKNOWN, myGroup->getId(),
351 //// SLVS_C_WHERE_DRAGGED, myGroup->getWorkplaneId(), 0.0,
352 //// aPoint[i], SLVS_E_UNKNOWN, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN);
353 //// aConstraint.h = myStorage->addConstraint(aConstraint);
354 //// mySlvsConstraints.push_back(aConstraint.h);