1 // File: SketchSolver_Constraint.cpp
2 // Created: 27 May 2014
3 // Author: Artem ZHIDKOV
5 #include "SketchSolver_Constraint.h"
6 #include <SketchSolver_Solver.h>
8 #include <ModelAPI_AttributeRefAttr.h>
9 #include <ModelAPI_Data.h>
11 #include <GeomDataAPI_Point.h>
12 #include <GeomDataAPI_Point2D.h>
15 SketchSolver_Constraint::SketchSolver_Constraint()
16 : myConstraint(boost::shared_ptr<SketchPlugin_Constraint>()),
17 myType(SLVS_C_UNKNOWN),
22 SketchSolver_Constraint::SketchSolver_Constraint(
23 boost::shared_ptr<SketchPlugin_Constraint> theConstraint)
24 : myConstraint(theConstraint),
27 myType = getType(myConstraint);
30 const int& SketchSolver_Constraint::getType(boost::shared_ptr<SketchPlugin_Constraint> theConstraint)
32 myType = SLVS_C_UNKNOWN;
36 // Assign empty names of attributes
37 myAttributesList.clear();
38 for (int i = 0; i < CONSTRAINT_ATTR_SIZE; i++)
39 myAttributesList.push_back(std::string());
41 const std::string& aConstraintKind = theConstraint->getKind();
42 // Constraint for coincidence of two points
43 if (aConstraintKind.compare("SketchConstraintCoincidence") == 0)
46 // Verify the constraint has only two attributes and they are points
47 int aPt2d = 0; // bit-mapped field, each bit indicates whether the attribute is 2D point
48 int aPt3d = 0; // bit-mapped field, the same information for 3D points
49 for (unsigned int indAttr = 0; indAttr < CONSTRAINT_ATTR_SIZE; indAttr++)
51 boost::shared_ptr<ModelAPI_AttributeRefAttr> anAttr =
52 boost::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
53 theConstraint->data()->attribute(CONSTRAINT_ATTRIBUTES[indAttr])
55 if (!anAttr) continue;
56 // Verify the attribute is a 2D point
57 boost::shared_ptr<GeomDataAPI_Point2D> aPoint2D =
58 boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(anAttr->attr());
61 aPt2d |= (1 << indAttr);
62 myAttributesList[anAttrPos++] = CONSTRAINT_ATTRIBUTES[indAttr];
65 // Verify the attribute is a 3D point
66 boost::shared_ptr<GeomDataAPI_Point> aPoint3D =
67 boost::dynamic_pointer_cast<GeomDataAPI_Point>(anAttr->attr());
70 aPt3d |= (1 << indAttr);
71 myAttributesList[anAttrPos++] = CONSTRAINT_ATTRIBUTES[indAttr];
74 // Attribute neither 2D nor 3D point is not supported by this type of constraint
77 // The constrained points should be in first and second positions,
78 // so the expected value of aPt2d or aPt3d is 3
79 if ((aPt2d == 3 && aPt3d == 0) || (aPt2d == 0 && aPt3d == 3))
80 myType = SLVS_C_POINTS_COINCIDENT;
81 // Constraint parameters are wrong
85 // Constraint for distance between point and another entity
86 if (aConstraintKind.compare("SketchConstraintDistance") == 0)
90 for (unsigned int indAttr = 0; indAttr < CONSTRAINT_ATTR_SIZE; indAttr++)
92 boost::shared_ptr<ModelAPI_AttributeRefAttr> anAttr =
93 boost::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
94 theConstraint->data()->attribute(CONSTRAINT_ATTRIBUTES[indAttr])
96 if (!anAttr) continue;
97 if (anAttr->isFeature())
98 { // verify posiible entities
99 const std::string& aKind = anAttr->feature()->getKind();
100 if (aKind.compare("SketchPoint") == 0)
102 myAttributesList[aNbPoints++] = CONSTRAINT_ATTRIBUTES[indAttr];
105 else if(aKind.compare("SketchLine") == 0)
107 // entities are placed starting from CONSTRAINT_ATTR_ENTITY_C attribute
108 myAttributesList[2 + aNbEntities++] = CONSTRAINT_ATTRIBUTES[indAttr];
109 myType = SLVS_C_PT_LINE_DISTANCE;
115 // Verify the attribute is a 2D point
116 boost::shared_ptr<GeomDataAPI_Point2D> aPoint2D =
117 boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(anAttr->attr());
120 myAttributesList[aNbPoints++] = CONSTRAINT_ATTRIBUTES[indAttr];
123 // Verify the attribute is a 3D point
124 boost::shared_ptr<GeomDataAPI_Point> aPoint3D =
125 boost::dynamic_pointer_cast<GeomDataAPI_Point>(anAttr->attr());
128 myAttributesList[aNbPoints++] = CONSTRAINT_ATTRIBUTES[indAttr];
133 // Verify the correctness of constraint arguments
134 if (aNbPoints == 2 && aNbEntities ==0)
135 myType = SLVS_C_PT_PT_DISTANCE;
136 else if (aNbPoints == 1 && aNbEntities == 1)
137 myType = SLVS_C_UNKNOWN;
141 // Constraint for two parallel/perpendicular lines
142 bool isParallel = (aConstraintKind.compare("SketchConstraintParallel") == 0);
143 bool isPerpendicular = (aConstraintKind.compare("SketchConstraintPerpendicular") == 0);
144 if (isParallel || isPerpendicular)
146 int aNbEntities = 2; // lines in SolveSpace constraints should started from CONSTRAINT_ATTR_ENTITY_C attribute
147 for (unsigned int indAttr = 0; indAttr < CONSTRAINT_ATTR_SIZE; indAttr++)
149 boost::shared_ptr<ModelAPI_AttributeRefAttr> anAttr =
150 boost::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
151 theConstraint->data()->attribute(CONSTRAINT_ATTRIBUTES[indAttr])
153 if (!anAttr || !anAttr->isFeature()) continue;
154 const std::string& aKind = anAttr->feature()->getKind();
155 if (aKind.compare("SketchLine") == 0)
157 myAttributesList[aNbEntities++] = CONSTRAINT_ATTRIBUTES[indAttr];
161 if (aNbEntities == 4)
162 myType = isParallel ? SLVS_C_PARALLEL : SLVS_C_PERPENDICULAR;
166 // Constraint for diameter of a circle
167 if (aConstraintKind.compare("SketchConstraintDiameter") == 0)
169 int aNbEntities = 2; // lines in SolveSpace constraints should started from CONSTRAINT_ATTR_ENTITY_C attribute
170 for (unsigned int indAttr = 0; indAttr < CONSTRAINT_ATTR_SIZE; indAttr++)
172 boost::shared_ptr<ModelAPI_AttributeRefAttr> anAttr =
173 boost::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
174 theConstraint->data()->attribute(CONSTRAINT_ATTRIBUTES[indAttr])
176 if (!anAttr || !anAttr->isFeature()) continue;
177 const std::string& aKind = anAttr->feature()->getKind();
178 if (aKind.compare("SketchCircle") == 0)
180 myAttributesList[aNbEntities++] = CONSTRAINT_ATTRIBUTES[indAttr];
184 if (aNbEntities == 3)
185 myType = SLVS_C_DIAMETER;
189 /// \todo Implement other kind of constrtaints