Salome HOME
12815acf314300a61a83ba916b62af4bf7efe1a6
[modules/shaper.git] / src / SketchSolver / SketchSolver_ConstraintRigid.cpp
1 #include <SketchSolver_ConstraintRigid.h>
2 #include <SketchSolver_Error.h>
3 #include <SketchSolver_Group.h>
4
5 #include <SketchPlugin_ConstraintRigid.h>
6
7 SketchSolver_ConstraintRigid::SketchSolver_ConstraintRigid(FeaturePtr theFeature)
8   : SketchSolver_Constraint(),
9     myBaseFeature(theFeature)
10 {
11   process();
12 }
13
14 void SketchSolver_ConstraintRigid::process()
15 {
16   cleanErrorMsg();
17   if ((!myBaseConstraint && !myBaseFeature) || !myStorage || myGroup == 0) {
18     /// TODO: Put error message here
19     return;
20   }
21   if (!mySlvsConstraints.empty()) // some data is changed, update constraint
22     update(myBaseConstraint);
23
24   double aValue;
25   std::vector<Slvs_hEntity> anEntities;
26   getAttributes(aValue, anEntities);
27
28   Slvs_Constraint aConstraint;
29   std::vector<Slvs_hConstraint>::iterator aConstrIter = mySlvsConstraints.begin();
30   bool isEmpty = aConstrIter == mySlvsConstraints.end();
31   std::vector<Slvs_hEntity>::const_iterator anEntIter = anEntities.begin();
32   for (; anEntIter != anEntities.end(); anEntIter++) {
33     if (*anEntIter == SLVS_E_UNKNOWN)
34       continue;
35     Slvs_hConstraint aConstrID = myStorage->isPointFixed(*anEntIter);
36     bool isForceUpdate = (aConstrID != SLVS_E_UNKNOWN && !myBaseConstraint);
37     if (isEmpty && !isForceUpdate) { // create new constraint
38       if (aConstrID != SLVS_E_UNKNOWN)
39         continue; // the coincident point is already fixed
40       aConstraint = Slvs_MakeConstraint(SLVS_C_UNKNOWN, myGroup->getId(), getType(), myGroup->getWorkplaneId(),
41           aValue, *anEntIter, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN);
42       aConstraint.h = myStorage->addConstraint(aConstraint);
43       mySlvsConstraints.push_back(aConstraint.h);
44       if (!myBaseConstraint)
45         myStorage->addTemporaryConstraint(aConstraint.h);
46     } else { // update already existent constraint
47       if (aConstrID == SLVS_E_UNKNOWN || myBaseConstraint)
48         aConstrID = *aConstrIter;
49       aConstraint = myStorage->getConstraint(aConstrID);
50       aConstraint.ptA = *anEntIter;
51       myStorage->addConstraint(aConstraint);
52       if (!myBaseConstraint)
53         myStorage->addTemporaryConstraint(aConstraint.h);
54       if (!isEmpty) {
55         aConstrIter++;
56         isEmpty = aConstrIter == mySlvsConstraints.end();
57       }
58     }
59   }
60 }
61
62
63 void SketchSolver_ConstraintRigid::getAttributes(
64     double& theValue,
65     std::vector<Slvs_hEntity>& theAttributes)
66 {
67   theValue = 0.0;
68   int aType = SLVS_E_UNKNOWN; // type of created entity
69   Slvs_hEntity anEntityID = SLVS_E_UNKNOWN;
70   if (myBaseConstraint) {
71     // Get the attribute of constraint
72     AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
73         myBaseConstraint->attribute(SketchPlugin_ConstraintRigid::ENTITY_A()));
74     if (!aRefAttr || !aRefAttr->isInitialized()) {
75       myErrorMsg = SketchSolver_Error::NOT_INITIALIZED();
76       return;
77     }
78     anEntityID = myGroup->getAttributeId(aRefAttr);
79     if (anEntityID == SLVS_E_UNKNOWN)
80       anEntityID = changeEntity(aRefAttr, aType);
81   } else {
82     anEntityID = myGroup->getFeatureId(myBaseFeature);
83     if (anEntityID == SLVS_E_UNKNOWN)
84       anEntityID = changeEntity(myBaseFeature, aType);
85   }
86
87   // Check the entity is complex
88   Slvs_Entity anEntity = myStorage->getEntity(anEntityID);
89   if (anEntity.point[0] != SLVS_E_UNKNOWN) {
90     for (int i = 0; i < 4 && anEntity.point[i]; i++)
91       theAttributes.push_back(anEntity.point[i]);
92   } else // simple entity
93     theAttributes.push_back(anEntityID);
94 }
95
96 bool SketchSolver_ConstraintRigid::remove(ConstraintPtr theConstraint)
97 {
98   cleanErrorMsg();
99   if (theConstraint && theConstraint != myBaseConstraint)
100     return false;
101   bool isFullyRemoved = true;
102   std::vector<Slvs_hConstraint>::iterator aCIter = mySlvsConstraints.begin();
103   for (; aCIter != mySlvsConstraints.end(); aCIter++)
104     isFullyRemoved = myStorage->removeConstraint(*aCIter) && isFullyRemoved;
105
106   if (isFullyRemoved) {
107     myFeatureMap.clear();
108     myAttributeMap.clear();
109     myValueMap.clear();
110   } else
111     cleanRemovedEntities();
112   return true;
113 }
114