Salome HOME
Place mirrored entities to correct group
[modules/shaper.git] / src / SketchSolver / SketchSolver_ConstraintMirror.cpp
1 #include <SketchSolver_ConstraintMirror.h>
2 #include <SketchSolver_Error.h>
3 #include <SketchSolver_Manager.h>
4
5 #include <ModelAPI_AttributeRefList.h>
6
7 void SketchSolver_ConstraintMirror::getAttributes(
8     EntityWrapperPtr& theMirrorLine,
9     std::vector<EntityWrapperPtr>& theBaseEntities,
10     std::vector<EntityWrapperPtr>& theMirrorEntities)
11 {
12   AttributePtr aMirLineAttr = myBaseConstraint->attribute(SketchPlugin_Constraint::ENTITY_A());
13   AttributeRefAttrPtr aMirLineRefAttr =
14       std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(aMirLineAttr);
15   if (!aMirLineRefAttr || !aMirLineRefAttr->isInitialized() || !aMirLineRefAttr->isObject()) {
16     myErrorMsg = SketchSolver_Error::NOT_INITIALIZED();
17     return;
18   }
19
20   myType = TYPE(myBaseConstraint);
21   myStorage->update(aMirLineAttr/*, myGroupID*/);
22   theMirrorLine = myStorage->entity(aMirLineAttr);
23
24   // Create SolveSpace entity for all features
25   AttributeRefListPtr aBaseRefList = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
26       myBaseConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
27   AttributeRefListPtr aMirroredRefList = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
28       myBaseConstraint->attribute(SketchPlugin_Constraint::ENTITY_C()));
29   myNumberOfObjects = aMirroredRefList->size();
30   if (!aBaseRefList || !aMirroredRefList) {
31     myErrorMsg = SketchSolver_Error::INCORRECT_MIRROR_ATTRIBUTE();
32     return;
33   }
34
35   std::list<ObjectPtr> aBaseList = aBaseRefList->list();
36   std::list<ObjectPtr> aMirroredList = aMirroredRefList->list();
37
38   FeaturePtr aFeature;
39   for (int i = 0; i < 2; i++) {
40     std::list<ObjectPtr>::iterator anIter = i == 0 ? aBaseList.begin() : aMirroredList.begin();
41     std::list<ObjectPtr>::iterator aEndIter = i == 0 ? aBaseList.end() : aMirroredList.end();
42     std::vector<EntityWrapperPtr>* aList = i == 0 ? &theBaseEntities : & theMirrorEntities;
43     for ( ; anIter != aEndIter; anIter++) {
44       aFeature = ModelAPI_Feature::feature(*anIter);
45       if (!aFeature)
46         continue;
47
48       myStorage->update(aFeature/*, myGroupID*/);
49       aList->push_back(myStorage->entity(aFeature));
50     }
51   }
52
53   // Mirrored entities are placed out-of-group by default, due to they are copies.
54   // Place them into current group manually.
55   std::vector<EntityWrapperPtr>::iterator aMirIt = theMirrorEntities.begin();
56   for (; aMirIt != theMirrorEntities.end(); ++aMirIt)
57     (*aMirIt)->setGroup(myGroupID);
58
59   if (theBaseEntities.size() > theMirrorEntities.size())
60     myErrorMsg = SketchSolver_Error::NOT_INITIALIZED();
61 }
62
63 void SketchSolver_ConstraintMirror::process()
64 {
65   cleanErrorMsg();
66   if (!myBaseConstraint || !myStorage || myGroupID == GID_UNKNOWN) {
67     // Not enough parameters are assigned
68     return;
69   }
70
71   EntityWrapperPtr aMirrorLine;
72   std::vector<EntityWrapperPtr> aBaseList;
73   std::vector<EntityWrapperPtr> aMirrorList;
74   getAttributes(aMirrorLine, aBaseList, aMirrorList);
75   if (!myErrorMsg.empty())
76     return;
77
78   if (aBaseList.size() != aMirrorList.size()) {
79     myErrorMsg = SketchSolver_Error::INCORRECT_MIRROR_ATTRIBUTE();
80     return;
81   }
82
83   std::list<ConstraintWrapperPtr> aNewConstraints;
84   SketchSolver_ConstraintType aConstrType = getType();
85   BuilderPtr aBuilder = SketchSolver_Manager::instance()->builder();
86   std::list<ConstraintWrapperPtr> aMirConstrList;
87
88   std::vector<EntityWrapperPtr>::iterator aBIt = aBaseList.begin();
89   std::vector<EntityWrapperPtr>::iterator aMIt = aMirrorList.begin();
90   for (; aBIt != aBaseList.end(); ++aBIt, ++aMIt) {
91     if ((*aBIt)->type() == ENTITY_ARC) {
92       // add new points on arcs and mirror them
93       EntityWrapperPtr aBasePnt = myStorage->calculateMiddlePoint(*aBIt, 0.5);
94       EntityWrapperPtr aMirrPnt = myStorage->calculateMiddlePoint(*aMIt, 0.5);
95       // point on base arc
96       aNewConstraints = aBuilder->createConstraint(myBaseConstraint, myGroupID, mySketchID,
97           CONSTRAINT_PT_ON_CIRCLE, 0.0, aBasePnt, EntityWrapperPtr(), *aBIt);
98       aMirConstrList.insert(aMirConstrList.end(), aNewConstraints.begin(), aNewConstraints.end());
99       // point on mirrored arc
100       aNewConstraints = aBuilder->createConstraint(myBaseConstraint, myGroupID, mySketchID,
101           CONSTRAINT_PT_ON_CIRCLE, 0.0, aMirrPnt, EntityWrapperPtr(), *aMIt);
102       aMirConstrList.insert(aMirConstrList.end(), aNewConstraints.begin(), aNewConstraints.end());
103       // mirror these points
104       aNewConstraints = aBuilder->createConstraint(myBaseConstraint, myGroupID, mySketchID,
105           aConstrType, 0.0, aBasePnt, aMirrPnt, aMirrorLine);
106       aMirConstrList.insert(aMirConstrList.end(), aNewConstraints.begin(), aNewConstraints.end());
107     }
108     aNewConstraints = aBuilder->createConstraint(
109         myBaseConstraint, myGroupID, mySketchID, aConstrType,
110         0.0, *aBIt, *aMIt, aMirrorLine);
111     aMirConstrList.insert(aMirConstrList.end(), aNewConstraints.begin(), aNewConstraints.end());
112   }
113
114   // update mirrored features to be in the current group
115   for (aMIt = aMirrorList.begin(); aMIt != aMirrorList.end(); ++aMIt)
116     myStorage->update((*aMIt)->baseFeature(), myGroupID);
117   myStorage->addConstraint(myBaseConstraint, aMirConstrList);
118 }
119
120
121 void SketchSolver_ConstraintMirror::update()
122 {
123   cleanErrorMsg();
124   AttributeRefListPtr aMirroredRefList = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
125     myBaseConstraint->attribute(SketchPlugin_Constraint::ENTITY_C()));
126   if (aMirroredRefList->size() != myNumberOfObjects) {
127     remove();
128     process();
129     return;
130   }
131   adjustConstraint();
132 }
133
134 void SketchSolver_ConstraintMirror::adjustConstraint()
135 {
136   BuilderPtr aBuilder = SketchSolver_Manager::instance()->builder();
137
138   const std::list<ConstraintWrapperPtr>& aConstraints = myStorage->constraint(myBaseConstraint);
139   std::list<ConstraintWrapperPtr>::const_iterator aCIt = aConstraints.begin();
140   for (; aCIt != aConstraints.end(); ++aCIt)
141     if ((*aCIt)->type() == CONSTRAINT_SYMMETRIC)
142       aBuilder->adjustConstraint(*aCIt);
143 }