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 <SketchPlugin_Line.h>
10 #include <ModelAPI_AttributeRefAttr.h>
11 #include <ModelAPI_Data.h>
13 #include <GeomDataAPI_Point.h>
14 #include <GeomDataAPI_Point2D.h>
17 SketchSolver_Constraint::SketchSolver_Constraint()
18 : myConstraint(boost::shared_ptr<SketchPlugin_Constraint>()),
19 myType(SLVS_C_UNKNOWN),
24 SketchSolver_Constraint::SketchSolver_Constraint(
25 boost::shared_ptr<SketchPlugin_Constraint> theConstraint)
26 : myConstraint(theConstraint),
29 myType = getType(myConstraint);
32 const int& SketchSolver_Constraint::getType(boost::shared_ptr<SketchPlugin_Constraint> theConstraint)
34 myType = SLVS_C_UNKNOWN;
38 // Assign empty names of attributes
39 myAttributesList.clear();
40 for (int i = 0; i < CONSTRAINT_ATTR_SIZE; i++)
41 myAttributesList.push_back(std::string());
43 const std::string& aConstraintKind = theConstraint->getKind();
44 // Constraint for coincidence of two points
45 if (aConstraintKind.compare("SketchConstraintCoincidence") == 0)
48 // Verify the constraint has only two attributes and they are points
49 int aPt2d = 0; // bit-mapped field, each bit indicates whether the attribute is 2D point
50 int aPt3d = 0; // bit-mapped field, the same information for 3D points
51 for (unsigned int indAttr = 0; indAttr < CONSTRAINT_ATTR_SIZE; indAttr++)
53 boost::shared_ptr<ModelAPI_AttributeRefAttr> anAttr =
54 boost::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
55 theConstraint->data()->attribute(CONSTRAINT_ATTRIBUTES[indAttr])
57 if (!anAttr) continue;
58 // Verify the attribute is a 2D point
59 boost::shared_ptr<GeomDataAPI_Point2D> aPoint2D =
60 boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(anAttr->attr());
63 aPt2d |= (1 << indAttr);
64 myAttributesList[anAttrPos++] = CONSTRAINT_ATTRIBUTES[indAttr];
67 // Verify the attribute is a 3D point
68 boost::shared_ptr<GeomDataAPI_Point> aPoint3D =
69 boost::dynamic_pointer_cast<GeomDataAPI_Point>(anAttr->attr());
72 aPt3d |= (1 << indAttr);
73 myAttributesList[anAttrPos++] = CONSTRAINT_ATTRIBUTES[indAttr];
76 // Attribute neither 2D nor 3D point is not supported by this type of constraint
79 // The constrained points should be in first and second positions,
80 // so the expected value of aPt2d or aPt3d is 3
81 if ((aPt2d == 3 && aPt3d == 0) || (aPt2d == 0 && aPt3d == 3))
82 myType = SLVS_C_POINTS_COINCIDENT;
83 // Constraint parameters are wrong
87 // Constraint for distance between point and another entity
88 if (aConstraintKind.compare("SketchConstraintDistance") == 0)
92 for (unsigned int indAttr = 0; indAttr < CONSTRAINT_ATTR_SIZE; indAttr++)
94 boost::shared_ptr<ModelAPI_AttributeRefAttr> anAttr =
95 boost::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
96 theConstraint->data()->attribute(CONSTRAINT_ATTRIBUTES[indAttr])
98 if (!anAttr) continue;
99 if (anAttr->isFeature() && anAttr->feature())
100 { // verify posiible entities
101 const std::string& aKind = anAttr->feature()->getKind();
102 if (aKind.compare("SketchPoint") == 0)
104 myAttributesList[aNbPoints++] = CONSTRAINT_ATTRIBUTES[indAttr];
107 else if(aKind.compare(SKETCH_LINE_KIND) == 0)
109 // entities are placed starting from CONSTRAINT_ATTR_ENTITY_C attribute
110 myAttributesList[2 + aNbEntities++] = CONSTRAINT_ATTRIBUTES[indAttr];
111 myType = SLVS_C_PT_LINE_DISTANCE;
117 // Verify the attribute is a 2D point
118 boost::shared_ptr<GeomDataAPI_Point2D> aPoint2D =
119 boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(anAttr->attr());
122 myAttributesList[aNbPoints++] = CONSTRAINT_ATTRIBUTES[indAttr];
125 // Verify the attribute is a 3D point
126 boost::shared_ptr<GeomDataAPI_Point> aPoint3D =
127 boost::dynamic_pointer_cast<GeomDataAPI_Point>(anAttr->attr());
130 myAttributesList[aNbPoints++] = CONSTRAINT_ATTRIBUTES[indAttr];
135 // Verify the correctness of constraint arguments
136 if (aNbPoints == 2 && aNbEntities ==0)
137 myType = SLVS_C_PT_PT_DISTANCE;
138 else if (aNbPoints == 1 && aNbEntities == 1)
139 myType = SLVS_C_UNKNOWN;
143 // Constraint for the given length of a line
144 if (aConstraintKind.compare("SketchConstraintLength") == 0)
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) continue;
154 if (anAttr->isFeature() && anAttr->feature() &&
155 anAttr->feature()->getKind().compare(SKETCH_LINE_KIND) == 0)
157 myAttributesList[aNbLines++] = CONSTRAINT_ATTRIBUTES[indAttr];
162 myType = SLVS_C_PT_PT_DISTANCE;
166 // Constraint for two parallel/perpendicular lines
167 bool isParallel = (aConstraintKind.compare("SketchConstraintParallel") == 0);
168 bool isPerpendicular = (aConstraintKind.compare("SketchConstraintPerpendicular") == 0);
169 if (isParallel || isPerpendicular)
171 int aNbEntities = 2; // lines in SolveSpace constraints should started from CONSTRAINT_ATTR_ENTITY_C attribute
172 for (unsigned int indAttr = 0; indAttr < CONSTRAINT_ATTR_SIZE; indAttr++)
174 boost::shared_ptr<ModelAPI_AttributeRefAttr> anAttr =
175 boost::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
176 theConstraint->data()->attribute(CONSTRAINT_ATTRIBUTES[indAttr])
178 if (!anAttr || !anAttr->isFeature()) continue;
179 const std::string& aKind = anAttr->feature()->getKind();
180 if (aKind.compare(SKETCH_LINE_KIND) == 0)
182 myAttributesList[aNbEntities++] = CONSTRAINT_ATTRIBUTES[indAttr];
186 if (aNbEntities == 4)
187 myType = isParallel ? SLVS_C_PARALLEL : SLVS_C_PERPENDICULAR;
191 // Constraint for radius of a circle or an arc of circle
192 if (aConstraintKind.compare("SketchConstraintRadius") == 0)
194 int aNbEntities = 2; // lines in SolveSpace constraints should started from CONSTRAINT_ATTR_ENTITY_C attribute
195 for (unsigned int indAttr = 0; indAttr < CONSTRAINT_ATTR_SIZE; indAttr++)
197 boost::shared_ptr<ModelAPI_AttributeRefAttr> anAttr =
198 boost::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
199 theConstraint->data()->attribute(CONSTRAINT_ATTRIBUTES[indAttr])
201 if (!anAttr || !anAttr->isFeature()) continue;
202 const std::string& aKind = anAttr->feature()->getKind();
203 if (aKind.compare("SketchCircle") == 0 || aKind.compare("SketchArc") == 0)
205 myAttributesList[aNbEntities++] = CONSTRAINT_ATTRIBUTES[indAttr];
209 if (aNbEntities == 3)
210 myType = SLVS_C_DIAMETER;
214 /// \todo Implement other kind of constrtaints