Salome HOME
First phase of SketchSolver refactoring
[modules/shaper.git] / src / SketchSolver / SketchSolver_ConstraintMovement.cpp
1 #include <SketchSolver_ConstraintMovement.h>
2 #include <SketchSolver_Error.h>
3 #include <SketchSolver_Manager.h>
4
5 #include <SketchPlugin_Arc.h>
6 #include <SketchPlugin_Circle.h>
7 #include <SketchPlugin_Line.h>
8 #include <SketchPlugin_Point.h>
9
10 #include <GeomDataAPI_Point2D.h>
11
12
13 void SketchSolver_ConstraintMovement::process()
14 {
15   cleanErrorMsg();
16   if (!myBaseFeature || !myStorage || myGroupID == GID_UNKNOWN) {
17     // Not enough parameters are initialized
18     return;
19   }
20
21   ParameterWrapperPtr aValue;
22   getAttributes(aValue, myMovedEntities);
23   if (!myErrorMsg.empty() || myMovedEntities.empty()) {
24     // Nothing to move, clear the feature to avoid changing its group
25     // after removing the Movement constraint.
26     myBaseFeature = FeaturePtr();
27     return;
28   }
29
30   std::vector<EntityWrapperPtr>::iterator anEntIt = myMovedEntities.begin();
31   for (; anEntIt != myMovedEntities.end(); ++anEntIt)
32     fixFeature(*anEntIt);
33 }
34
35
36 static std::list<EntityWrapperPtr> movedEntities(
37     EntityWrapperPtr theOld, StoragePtr theOldStorage,
38     EntityWrapperPtr theNew, StoragePtr theNewStorage)
39 {
40   bool isFullyMoved = true;
41   std::list<EntityWrapperPtr> aMoved;
42   if (theOld->isEqual(theNew))
43     return aMoved;
44
45   std::list<EntityWrapperPtr> anOldSubs = theOld->subEntities();
46   std::list<EntityWrapperPtr> aNewSubs = theNew->subEntities();
47   std::list<EntityWrapperPtr>::const_iterator anOldIt = anOldSubs.begin();
48   std::list<EntityWrapperPtr>::const_iterator aNewIt = aNewSubs.begin();
49   for (; anOldIt != anOldSubs.end() && aNewIt != aNewSubs.end(); ++anOldIt, ++aNewIt) {
50     std::list<EntityWrapperPtr> aMovedSubs = movedEntities(
51         *anOldIt, theOldStorage, *aNewIt, theNewStorage);
52     if (aMovedSubs.size() != 1 || aMovedSubs.front() != *anOldIt)
53       isFullyMoved = false;
54     aMoved.insert(aMoved.end(), aMovedSubs.begin(), aMovedSubs.end());
55   }
56   if (isFullyMoved) {
57     aMoved.clear();
58     aMoved.push_back(theOld);
59   }
60   return aMoved;
61 }
62
63
64 void SketchSolver_ConstraintMovement::getAttributes(
65     ParameterWrapperPtr& theValue,
66     std::vector<EntityWrapperPtr>& theAttributes)
67 {
68   // There will be build entities, according to the fixed feature, in the separate storage
69   // to check whether any point is moved
70   BuilderPtr aBuilder = SketchSolver_Manager::instance()->builder();
71   StoragePtr anOtherStorage = aBuilder->createStorage(myGroupID);
72   anOtherStorage->setSketch(myStorage->sketch());
73   if (!anOtherStorage->update(myBaseFeature, myGroupID))
74     return;
75   EntityWrapperPtr aNewEntity = anOtherStorage->entity(myBaseFeature);
76   EntityWrapperPtr anOldEntity = myStorage->entity(myBaseFeature);
77
78   std::list<EntityWrapperPtr> aMoved;
79   if (aNewEntity && anOldEntity)
80     aMoved = movedEntities(anOldEntity, myStorage, aNewEntity, anOtherStorage);
81   else {
82     // get attributes moved
83     std::list<AttributePtr> anAttrList =
84         myBaseFeature->data()->attributes(GeomDataAPI_Point2D::typeId());
85     std::list<AttributePtr>::const_iterator anIt = anAttrList.begin();
86     for (; anIt != anAttrList.end(); ++anIt) {
87       aNewEntity = anOtherStorage->entity(*anIt);
88       anOldEntity = myStorage->entity(*anIt);
89       if (!aNewEntity || !anOldEntity)
90         continue;
91       std::list<EntityWrapperPtr> aMovedAttr = movedEntities(
92           anOldEntity, myStorage, aNewEntity, anOtherStorage);
93       aMoved.insert(aMoved.end(), aMovedAttr.begin(), aMovedAttr.end());
94     }
95   }
96   theAttributes.clear();
97   theAttributes.insert(theAttributes.begin(), aMoved.begin(), aMoved.end());
98 }