]> SALOME platform Git repositories - modules/shaper.git/blob - src/SketchSolver/SketchSolver_ConstraintCoincidence.cpp
Salome HOME
First phase of SketchSolver refactoring
[modules/shaper.git] / src / SketchSolver / SketchSolver_ConstraintCoincidence.cpp
1 #include <SketchSolver_ConstraintCoincidence.h>
2 #include <SketchSolver_Error.h>
3 #include <SketchSolver_Manager.h>
4
5 ////#include <SketchPlugin_Point.h>
6 ////#include <GeomDataAPI_Point2D.h>
7 ////
8 ////#include <map>
9
10 void SketchSolver_ConstraintCoincidence::getAttributes(
11     double& theValue,
12     std::vector<EntityWrapperPtr>& theAttributes)
13 {
14   SketchSolver_Constraint::getAttributes(theValue, theAttributes);
15   if (!myErrorMsg.empty() || !theAttributes[0]) {
16     theAttributes.clear();
17     return;
18   }
19
20   if (theAttributes[1]) {
21     myType = CONSTRAINT_PT_PT_COINCIDENT;
22     // Set the slave (second) point the same as master (first) point.
23     // This will allow to skip adding point-point coincidence to the set of constraints
24     // and give us speed-up in solving the set of equations
25     myStorage->addCoincidentPoints(theAttributes[0], theAttributes[1]);
26   }
27   else if (theAttributes[2]) {
28     // check the type of entity (line or circle)
29     SketchSolver_EntityType anEntType = theAttributes[2]->type();
30     if (anEntType == ENTITY_LINE)
31       myType = CONSTRAINT_PT_ON_LINE;
32     else if (anEntType == ENTITY_CIRCLE || anEntType == ENTITY_ARC)
33       myType = CONSTRAINT_PT_ON_CIRCLE;
34     else
35       myErrorMsg = SketchSolver_Error::INCORRECT_ATTRIBUTE();
36   } else
37     myErrorMsg = SketchSolver_Error::INCORRECT_ATTRIBUTE();
38 }
39
40
41 static bool isBase(const std::list<ConstraintWrapperPtr>& theConstraints, AttributePtr theAttribute)
42 {
43   AttributePtr anAttribute = theAttribute;
44   FeaturePtr aFeature;
45   AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
46   if (aRefAttr) {
47     if (aRefAttr->isObject())
48       aFeature = ModelAPI_Feature::feature(aRefAttr->object());
49     else
50       anAttribute = aRefAttr->attr();
51   }
52
53   std::list<ConstraintWrapperPtr>::const_iterator aCIt = theConstraints.begin();
54   for (; aCIt != theConstraints.end(); ++aCIt) {
55     std::list<EntityWrapperPtr> aSubs = (*aCIt)->entities();
56     std::list<EntityWrapperPtr>::const_iterator aSIt = aSubs.begin();
57     for (; aSIt != aSubs.end(); ++aSIt)
58       if ((aFeature && (*aSIt)->isBase(aFeature)) ||
59          (!aFeature && (*aSIt)->isBase(anAttribute)))
60         return true;
61   }
62   return false;
63 }
64
65 ////bool SketchSolver_ConstraintCoincidence::isCoincide(
66 ////    std::shared_ptr<SketchSolver_ConstraintCoincidence> theConstraint) const
67 ////{
68 ////  std::list<ConstraintPtr>::const_iterator anOtherCIt = theConstraint->myConstraints.begin();
69 ////  for (; anOtherCIt != theConstraint->myConstraints.end(); ++anOtherCIt) {
70 ////    std::list<ConstraintPtr>::const_iterator aCIt = myConstraints.begin();
71 ////    for (; aCIt != myConstraints.end(); ++aCIt) {
72 ////      std::list<ConstraintWrapperPtr> aWrappers = myStorage->constraint(*aCIt);
73 ////      if (isBase(aWrappers, (*anOtherCIt)->attribute(SketchPlugin_Constraint::ENTITY_A())) ||
74 ////         (isBase(aWrappers, (*anOtherCIt)->attribute(SketchPlugin_Constraint::ENTITY_B()))))
75 ////        return true;
76 ////    }
77 ////  }
78 ////  return false;
79 ////}
80 ////
81 ////void SketchSolver_ConstraintCoincidence::attach(
82 ////    std::shared_ptr<SketchSolver_ConstraintCoincidence> theConstraint)
83 ////{
84 ////  cleanErrorMsg();
85 ////  ConstraintWrapperPtr aFirstConstraint = myStorage->constraint(myConstraints.front()).front();
86 ////  EntityWrapperPtr aMasterPoint = aFirstConstraint->entities().front();
87 ////
88 ////  // Set points from theConstraint equal to master point
89 ////  const std::list<ConstraintPtr>& anOtherConstraints = theConstraint->myConstraints;
90 ////  std::list<ConstraintPtr>::const_iterator anOtherCIt = anOtherConstraints.begin();
91 ////  bool isFirstUpd = false;
92 ////  for (; anOtherCIt != anOtherConstraints.end(); ++anOtherCIt) {
93 ////    std::list<ConstraintWrapperPtr> aSolverConstraints = myStorage->constraint(*anOtherCIt);
94 ////    std::list<ConstraintWrapperPtr>::iterator aSCIt = aSolverConstraints.begin();
95 ////    // First point in each constraint is the same (master point of theConstraint),
96 ////    // it should be updated only once.
97 ////    if (!isFirstUpd) {
98 ////      EntityWrapperPtr anOtherMasterPoint = (*aSCIt)->entities().front();
99 ////      myStorage->addCoincidentPoints(aMasterPoint, anOtherMasterPoint);
100 ////      isFirstUpd = true;
101 ////    }
102 ////    // Update all slave points
103 ////    for (; aSCIt != aSolverConstraints.end(); ++aSCIt) {
104 ////      std::list<EntityWrapperPtr> aSubs = (*aSCIt)->entities();
105 ////      std::list<EntityWrapperPtr>::iterator aSubIt = aSubs.begin();
106 ////      for (++aSubIt; aSubIt != aSubs.end(); ++aSubIt)
107 ////        myStorage->addCoincidentPoints(aMasterPoint, *aSubIt);
108 ////    }
109 ////    // add constraint to myConstraints
110 ////    myConstraints.push_back(*anOtherCIt);
111 ////  }
112 ////
113 ////  // Remove constraints from theConstraint
114 ////  std::vector<Slvs_hConstraint>::iterator aCIter = theConstraint->mySlvsConstraints.begin();
115 ////  for (; aCIter != theConstraint->mySlvsConstraints.end(); aCIter++)
116 ////    theConstraint->myStorage->removeConstraint(*aCIter);
117 ////
118 ////  if (myStorage == theConstraint->myStorage) {
119 ////    // Clean removed items
120 ////    std::set<Slvs_hParam> aRemParams;
121 ////    std::set<Slvs_hEntity> aRemEnts;
122 ////    std::set<Slvs_hConstraint> aRemConstr;
123 ////    theConstraint->myStorage->getRemoved(aRemParams, aRemEnts, aRemConstr);
124 ////
125 ////    if (!aRemEnts.empty()) {
126 ////      std::map<FeaturePtr, Slvs_hEntity>::iterator aFeatIt = theConstraint->myFeatureMap.begin();
127 ////      while (aFeatIt != theConstraint->myFeatureMap.end()) {
128 ////        if (aRemEnts.find(aFeatIt->second) != aRemEnts.end()) {
129 ////          // remove feature
130 ////          std::map<FeaturePtr, Slvs_hEntity>::iterator aRemoveIt = aFeatIt++;
131 ////          theConstraint->myFeatureMap.erase(aRemoveIt);
132 ////        } else
133 ////          ++aFeatIt;
134 ////      }
135 ////      std::map<AttributePtr, Slvs_hEntity>::iterator anAttrIt = theConstraint->myAttributeMap.begin();
136 ////      while (anAttrIt != theConstraint->myAttributeMap.end()) {
137 ////        if (aRemEnts.find(anAttrIt->second) != aRemEnts.end()) {
138 ////          // remove attribute
139 ////          std::map<AttributePtr, Slvs_hEntity>::iterator aRemoveIt = anAttrIt++;
140 ////          theConstraint->myAttributeMap.erase(aRemoveIt);
141 ////        } else
142 ////          ++anAttrIt;
143 ////      }
144 ////    }
145 ////  }
146 ////
147 ////  // Copy data.
148 ////  addConstraint(theConstraint->myBaseConstraint);
149 ////  std::map<ConstraintPtr, Slvs_hConstraint>::iterator aConstrIter =
150 ////      theConstraint->myExtraCoincidence.begin();
151 ////  for (; aConstrIter != theConstraint->myExtraCoincidence.end(); aConstrIter++)
152 ////    addConstraint(aConstrIter->first);
153 ////  // Clear the lists to not remove the entities on destruction
154 ////  theConstraint->mySlvsConstraints.clear();
155 ////  theConstraint->myFeatureMap.clear();
156 ////  theConstraint->myAttributeMap.clear();
157 ////}
158
159 ////Slvs_hConstraint SketchSolver_ConstraintCoincidence::addConstraint(
160 ////    Slvs_hEntity thePoint1, Slvs_hEntity thePoint2)
161 ////{
162 ////  if (thePoint1 == thePoint2)
163 ////    return SLVS_E_UNKNOWN;
164 ////
165 ////  bool hasDuplicated = myStorage->hasDuplicatedConstraint();
166 ////  Slvs_Constraint aNewConstraint = Slvs_MakeConstraint(SLVS_E_UNKNOWN, myGroup->getId(),
167 ////      SLVS_C_POINTS_COINCIDENT, myGroup->getWorkplaneId(), 0.0, thePoint1, thePoint2, 
168 ////      SLVS_E_UNKNOWN, SLVS_E_UNKNOWN);
169 ////  Slvs_hConstraint aNewID = myStorage->addConstraint(aNewConstraint);
170 ////  if (!hasDuplicated && myStorage->hasDuplicatedConstraint()) {
171 ////    // the duplicated constraint appears
172 ////    myStorage->removeConstraint(aNewID);
173 ////    return SLVS_E_UNKNOWN;
174 ////  }
175 ////  mySlvsConstraints.push_back(aNewID);
176 ////  return aNewID;
177 ////}
178 ////
179 ////Slvs_hConstraint SketchSolver_ConstraintCoincidence::addPointOnEntity(
180 ////    Slvs_hEntity thePoint, Slvs_hEntity theEntity)
181 ////{
182 ////  // Check the point is not coincident with boundaries of the entity
183 ////  Slvs_Entity anEnt = myStorage->getEntity(theEntity);
184 ////  int aPos = anEnt.type == SLVS_E_LINE_SEGMENT ? 0 : 1;
185 ////  for (; anEnt.point[aPos] != SLVS_E_UNKNOWN; aPos++)
186 ////    if (anEnt.point[aPos] == thePoint ||
187 ////        myStorage->isCoincident(anEnt.point[aPos], thePoint))
188 ////      return SLVS_E_UNKNOWN;
189 ////
190 ////  bool hasDuplicated = myStorage->hasDuplicatedConstraint();
191 ////  Slvs_Constraint aBaseCoincidence = myStorage->getConstraint(mySlvsConstraints.front());
192 ////  Slvs_hConstraint aType = anEnt.type == SLVS_E_LINE_SEGMENT ?
193 ////      SLVS_C_PT_ON_LINE : SLVS_C_PT_ON_CIRCLE;
194 ////  Slvs_Constraint aNewConstraint = Slvs_MakeConstraint(SLVS_E_UNKNOWN, myGroup->getId(),
195 ////      aType, myGroup->getWorkplaneId(), 0.0, aBaseCoincidence.ptA, SLVS_E_UNKNOWN,
196 ////      theEntity, SLVS_E_UNKNOWN);
197 ////  Slvs_hConstraint aNewID = myStorage->addConstraint(aNewConstraint);
198 ////  if (!hasDuplicated && myStorage->hasDuplicatedConstraint()) {
199 ////    // the duplicated constraint appears
200 ////    myStorage->removeConstraint(aNewID);
201 ////    return SLVS_E_UNKNOWN;
202 ////  }
203 ////  mySlvsConstraints.push_back(aNewID);
204 ////  return aNewID;
205 ////}
206 ////
207 ////void SketchSolver_ConstraintCoincidence::addConstraint(ConstraintPtr theConstraint)
208 ////{
209 ////  if (mySlvsConstraints.empty()) {
210 ////    // This constraint is empty, rebuild it from scratch
211 ////    myBaseConstraint = theConstraint;
212 ////    process();
213 ////    return;
214 ////  }
215 ////
216 ////  std::list<AttributePtr> anAttrList =
217 ////      theConstraint->data()->attributes(ModelAPI_AttributeRefAttr::typeId());
218 ////  std::list<AttributePtr>::iterator anIter = anAttrList.begin();
219 ////  std::vector<Slvs_hEntity> aPoints;
220 ////  Slvs_hEntity anEntity = SLVS_E_UNKNOWN;
221 ////  int anEntType;
222 ////  for (; anIter != anAttrList.end(); anIter++) {
223 ////    Slvs_hEntity aPointID = SLVS_E_UNKNOWN;
224 ////    AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anIter);
225 ////    if (!aRefAttr)
226 ////      continue;
227 ////
228 ////    AttributePtr aPointAttr;
229 ////    if (aRefAttr->isObject()) {
230 ////      FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttr->object());
231 ////      std::map<FeaturePtr, Slvs_hEntity>::const_iterator aFeatFound = 
232 ////          myFeatureMap.find(aFeature);
233 ////      if (aFeatFound != myFeatureMap.end())
234 ////        anEntity = aFeatFound->second;
235 ////      else {
236 ////        anEntity = myGroup->getFeatureId(aFeature);
237 ////        if (anEntity == SLVS_E_UNKNOWN)
238 ////          anEntity = changeEntity(aFeature, anEntType);
239 ////        else {
240 ////          myFeatureMap[aFeature] = anEntity;
241 ////          // Obtain relations between attributes of the feature and SolveSpace entities
242 ////          std::list<AttributePtr> anAttrList =
243 ////              aFeature->data()->attributes(GeomDataAPI_Point2D::typeId());
244 ////          std::list<AttributePtr>::iterator anIt = anAttrList.begin();
245 ////          for (; anIt != anAttrList.end(); ++anIt) {
246 ////            Slvs_hEntity anAttrID = myGroup->getAttributeId(*anIt);
247 ////            if (anAttrID != SLVS_E_UNKNOWN)
248 ////              myAttributeMap[*anIt] = anAttrID;
249 ////          }
250 ////        }
251 ////      }
252 ////      // If the feature is a point, add it to the list of coincident points
253 ////      if (aFeature->getKind() == SketchPlugin_Point::ID()) {
254 ////        aPointID = anEntity;
255 ////        anEntity = SLVS_E_UNKNOWN;
256 ////        aPointAttr = aFeature->attribute(SketchPlugin_Point::COORD_ID());
257 ////      }
258 ////    } else {
259 ////      aPointAttr = aRefAttr->attr();
260 ////      std::map<AttributePtr, Slvs_hEntity>::const_iterator anAttrFound =
261 ////          myAttributeMap.find(aPointAttr);
262 ////      if (anAttrFound != myAttributeMap.end())
263 ////        aPointID = anAttrFound->second;
264 ////      else {
265 ////        aPointID = myGroup->getAttributeId(aPointAttr);
266 ////        if (aPointID == SLVS_E_UNKNOWN)
267 ////          aPointID = changeEntity(aPointAttr, anEntType);
268 ////      }
269 ////    }
270 ////
271 ////    if (aPointAttr) { // the point is found
272 ////      aPoints.push_back(aPointID);
273 ////      myCoincidentPoints.insert(aPointAttr);
274 ////      myAttributeMap[aPointAttr] = aPointID;
275 ////    }
276 ////  }
277 ////
278 ////  Slvs_hConstraint aNewConstr = SLVS_E_UNKNOWN;
279 ////  if (anEntity != SLVS_E_UNKNOWN)
280 ////    aNewConstr = addPointOnEntity(aPoints.front(), anEntity);
281 ////  else { // coincidence between two points
282 ////    Slvs_Constraint aBaseCoincidence = myStorage->getConstraint(mySlvsConstraints.front());
283 ////    std::vector<Slvs_hEntity>::const_iterator aPtIter = aPoints.begin();
284 ////    for (; aPtIter != aPoints.end(); aPtIter++) {
285 ////      Slvs_hConstraint aC = addConstraint(aBaseCoincidence.ptA, *aPtIter);
286 ////      if (aC != SLVS_E_UNKNOWN)
287 ////        aNewConstr = aC;
288 ////    }
289 ////  }
290 ////  myExtraCoincidence[theConstraint] = aNewConstr;
291 ////}
292
293 ////bool SketchSolver_ConstraintCoincidence::remove(ConstraintPtr theConstraint)
294 ////{
295 ////  cleanErrorMsg();
296 ////  if (mySlvsConstraints.empty())
297 ////    return true;
298 ////  ConstraintPtr aConstraint = theConstraint ? theConstraint : myBaseConstraint;
299 ////  int aPos = -1; // position of constraint in the list (-1 for base constraint)
300 ////  std::map<ConstraintPtr, Slvs_hConstraint>::iterator anExtraIt;
301 ////  if (aConstraint != myBaseConstraint) {
302 ////    anExtraIt = myExtraCoincidence.find(aConstraint);
303 ////    if (anExtraIt == myExtraCoincidence.end())
304 ////      return false; // there is no constraint, which is specified to remove
305 ////    else {
306 ////      bool isEmpty = anExtraIt->second == SLVS_E_UNKNOWN;
307 ////      if (!isEmpty) {
308 ////        isEmpty = true;
309 ////        for (aPos = 0; aPos < (int)mySlvsConstraints.size(); aPos++)
310 ////          if (mySlvsConstraints[aPos] == anExtraIt->second) {
311 ////            isEmpty = false;
312 ////            break;
313 ////          }
314 ////        aPos -= 1;
315 ////      }
316 ////      myExtraCoincidence.erase(anExtraIt);
317 ////      if (isEmpty)
318 ////        return false;
319 ////    }
320 ////  }
321 ////
322 ////  bool isFullyRemoved = myStorage->removeConstraint(mySlvsConstraints[aPos+1]);
323 ////  mySlvsConstraints.erase(mySlvsConstraints.begin() + (1+aPos));
324 ////  if (aPos < 0 && !myExtraCoincidence.empty()) {
325 ////    anExtraIt = myExtraCoincidence.begin();
326 ////    // Remove invalid constraints
327 ////    while (anExtraIt != myExtraCoincidence.end()) {
328 ////      if (!anExtraIt->first->data() || !anExtraIt->first->data()->isValid()) {
329 ////        std::map<ConstraintPtr, Slvs_hConstraint>::iterator aTempIt = anExtraIt++;
330 ////        if (aTempIt->first != SLVS_E_UNKNOWN) {
331 ////          myStorage->removeConstraint(aTempIt->second);
332 ////          std::vector<Slvs_hConstraint>::iterator anIt = mySlvsConstraints.begin();
333 ////          for (; anIt != mySlvsConstraints.end(); anIt++)
334 ////            if (*anIt == aTempIt->second) {
335 ////              mySlvsConstraints.erase(anIt);
336 ////              break;
337 ////            }
338 ////        }
339 ////        myExtraCoincidence.erase(aTempIt);
340 ////        continue;
341 ////      }
342 ////      anExtraIt++;
343 ////    }
344 ////    // Find first non-extra conststraint
345 ////    anExtraIt = myExtraCoincidence.begin();
346 ////    while (anExtraIt != myExtraCoincidence.end() && anExtraIt->second == SLVS_E_UNKNOWN)
347 ////      anExtraIt++;
348 ////    if (anExtraIt != myExtraCoincidence.end()) {
349 ////      // Need to specify another base coincidence constraint
350 ////      myBaseConstraint = anExtraIt->first;
351 ////      myExtraCoincidence.erase(anExtraIt);
352 ////      if (mySlvsConstraints.empty()) {
353 ////        std::vector<Slvs_hConstraint>::iterator aCIter = mySlvsConstraints.begin();
354 ////        Slvs_Constraint aBase = myStorage->getConstraint(*aCIter);
355 ////        for (++aCIter; aCIter != mySlvsConstraints.end(); aCIter++) {
356 ////          Slvs_Constraint aConstr = myStorage->getConstraint(*aCIter);
357 ////          aConstr.ptA = aBase.ptA;
358 ////          myStorage->updateConstraint(aConstr);
359 ////        }
360 ////      }
361 ////    }
362 ////  }
363 ////  // Clear removed attributes
364 ////  std::set<Slvs_hParam> aParamRemoved;
365 ////  std::set<Slvs_hEntity> anEntRemoved;
366 ////  std::set<Slvs_hConstraint> aConstrRemoved;
367 ////  myStorage->getRemoved(aParamRemoved, anEntRemoved, aConstrRemoved);
368 ////  std::map<AttributePtr, Slvs_hEntity>::iterator anAttrIter = myAttributeMap.begin();
369 ////  while (anAttrIter != myAttributeMap.end()) {
370 ////    if (anEntRemoved.find(anAttrIter->second) != anEntRemoved.end()) {
371 ////      std::map<AttributePtr, Slvs_hEntity>::iterator aTempIt = anAttrIter++;
372 ////      myCoincidentPoints.erase(aTempIt->first);
373 ////      myAttributeMap.erase(aTempIt);
374 ////      continue;
375 ////    }
376 ////    anAttrIter++;
377 ////  }
378 ////
379 ////  // Go through remaining extra coincidence and try to add or remove them
380 ////  anExtraIt = myExtraCoincidence.begin();
381 ////  while (anExtraIt != myExtraCoincidence.end()) {
382 ////    if (anExtraIt->first == SLVS_E_UNKNOWN) {
383 ////      if (!anExtraIt->first->data() || !anExtraIt->first->data()->isValid()) {
384 ////        std::map<ConstraintPtr, Slvs_hConstraint>::iterator aTempIt = anExtraIt++;
385 ////        myExtraCoincidence.erase(aTempIt);
386 ////        continue;
387 ////      }
388 ////      if (mySlvsConstraints.empty()) {
389 ////        myBaseConstraint = anExtraIt->first;
390 ////        std::map<ConstraintPtr, Slvs_hConstraint>::iterator aTempIt = anExtraIt++;
391 ////        myExtraCoincidence.erase(aTempIt);
392 ////        process();
393 ////        continue;
394 ////      } else
395 ////        addConstraint(anExtraIt->first);
396 ////    }
397 ////    anExtraIt++;
398 ////  }
399 ////  return mySlvsConstraints.empty();
400 ////}
401