Salome HOME
Managing of several groups with conflicting constraints on the same sketch plane
[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 ((*anOldIt)->type() == ENTITY_POINT && // check only the points to be moved (because arcs in PlaneGCS have scalar subs too)
53        (aMovedSubs.size() != 1 || aMovedSubs.front() != *anOldIt))
54       isFullyMoved = false;
55     aMoved.insert(aMoved.end(), aMovedSubs.begin(), aMovedSubs.end());
56   }
57   if (isFullyMoved) {
58     aMoved.clear();
59     aMoved.push_back(theOld);
60   }
61   return aMoved;
62 }
63
64
65 void SketchSolver_ConstraintMovement::getAttributes(
66     ParameterWrapperPtr& theValue,
67     std::vector<EntityWrapperPtr>& theAttributes)
68 {
69   // There will be build entities, according to the fixed feature, in the separate storage
70   // to check whether any point is moved
71   BuilderPtr aBuilder = SketchSolver_Manager::instance()->builder();
72   StoragePtr anOtherStorage = aBuilder->createStorage(myGroupID);
73   anOtherStorage->setSketch(myStorage->sketch());
74   if (!anOtherStorage->update(myBaseFeature, myGroupID))
75     return;
76   EntityWrapperPtr aNewEntity = anOtherStorage->entity(myBaseFeature);
77   EntityWrapperPtr anOldEntity = myStorage->entity(myBaseFeature);
78
79   std::list<EntityWrapperPtr> aMoved;
80   if (aNewEntity && anOldEntity)
81     aMoved = movedEntities(anOldEntity, myStorage, aNewEntity, anOtherStorage);
82   else {
83     // get attributes moved
84     std::list<AttributePtr> anAttrList =
85         myBaseFeature->data()->attributes(GeomDataAPI_Point2D::typeId());
86     std::list<AttributePtr>::const_iterator anIt = anAttrList.begin();
87     for (; anIt != anAttrList.end(); ++anIt) {
88       aNewEntity = anOtherStorage->entity(*anIt);
89       anOldEntity = myStorage->entity(*anIt);
90       if (!aNewEntity || !anOldEntity)
91         continue;
92       std::list<EntityWrapperPtr> aMovedAttr = movedEntities(
93           anOldEntity, myStorage, aNewEntity, anOtherStorage);
94       aMoved.insert(aMoved.end(), aMovedAttr.begin(), aMovedAttr.end());
95     }
96   }
97   theAttributes.clear();
98   theAttributes.insert(theAttributes.begin(), aMoved.begin(), aMoved.end());
99 }
100
101 bool SketchSolver_ConstraintMovement::remove()
102 {
103   cleanErrorMsg();
104   // Move fixed entities back to the current group
105   std::vector<EntityWrapperPtr>::iterator aMoveIt = myMovedEntities.begin();
106   for (; aMoveIt != myMovedEntities.end(); ++aMoveIt) {
107     if ((*aMoveIt)->baseAttribute())
108       myStorage->update((*aMoveIt)->baseAttribute(), myGroupID);
109     else if ((*aMoveIt)->baseFeature())
110       myStorage->update((*aMoveIt)->baseFeature(), myGroupID);
111   }
112
113   // Remove base feature
114   if (myBaseFeature)
115     myStorage->removeEntity(myBaseFeature);
116   return true;
117 }