]> SALOME platform Git repositories - modules/shaper.git/blob - src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Tools.cpp
Salome HOME
Update copyrights
[modules/shaper.git] / src / SketchSolver / PlaneGCSSolver / PlaneGCSSolver_Tools.cpp
1 // Copyright (C) 2014-2019  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #include <PlaneGCSSolver_Tools.h>
21 #include <PlaneGCSSolver_EdgeWrapper.h>
22 #include <PlaneGCSSolver_PointWrapper.h>
23 #include <PlaneGCSSolver_ScalarWrapper.h>
24 #include <PlaneGCSSolver_ConstraintWrapper.h>
25
26 #include <SketchSolver_Constraint.h>
27 #include <SketchSolver_ConstraintAngle.h>
28 #include <SketchSolver_ConstraintCoincidence.h>
29 #include <SketchSolver_ConstraintCollinear.h>
30 #include <SketchSolver_ConstraintDistance.h>
31 #include <SketchSolver_ConstraintEqual.h>
32 #include <SketchSolver_ConstraintFixed.h>
33 #include <SketchSolver_ConstraintLength.h>
34 #include <SketchSolver_ConstraintMiddle.h>
35 #include <SketchSolver_ConstraintMirror.h>
36 #include <SketchSolver_ConstraintTangent.h>
37 #include <SketchSolver_ConstraintMultiRotation.h>
38 #include <SketchSolver_ConstraintMultiTranslation.h>
39
40 #include <SketchPlugin_ConstraintAngle.h>
41 #include <SketchPlugin_ConstraintCoincidence.h>
42 #include <SketchPlugin_ConstraintCollinear.h>
43 #include <SketchPlugin_ConstraintDistance.h>
44 #include <SketchPlugin_ConstraintDistanceHorizontal.h>
45 #include <SketchPlugin_ConstraintDistanceVertical.h>
46 #include <SketchPlugin_ConstraintEqual.h>
47 #include <SketchPlugin_ConstraintLength.h>
48 #include <SketchPlugin_ConstraintMiddle.h>
49 #include <SketchPlugin_ConstraintMirror.h>
50 #include <SketchPlugin_ConstraintRigid.h>
51 #include <SketchPlugin_ConstraintTangent.h>
52 #include <SketchPlugin_Line.h>
53 #include <SketchPlugin_MultiRotation.h>
54 #include <SketchPlugin_MultiTranslation.h>
55
56 #include <cmath>
57
58
59 #define GCS_EDGE_WRAPPER(x)   std::dynamic_pointer_cast<PlaneGCSSolver_EdgeWrapper>(x)
60 #define GCS_POINT_WRAPPER(x)  std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(x)
61 #define GCS_SCALAR_WRAPPER(x) std::dynamic_pointer_cast<PlaneGCSSolver_ScalarWrapper>(x)
62
63
64
65 static ConstraintWrapperPtr
66   createConstraintCoincidence(std::shared_ptr<PlaneGCSSolver_PointWrapper> thePoint1,
67                               std::shared_ptr<PlaneGCSSolver_PointWrapper> thePoint2);
68 static ConstraintWrapperPtr
69   createConstraintPointOnEntity(const SketchSolver_ConstraintType& theType,
70                                 std::shared_ptr<PlaneGCSSolver_PointWrapper> thePoint,
71                                 std::shared_ptr<PlaneGCSSolver_EdgeWrapper> theEntity);
72 static ConstraintWrapperPtr
73   createConstraintDistancePointPoint(std::shared_ptr<PlaneGCSSolver_ScalarWrapper> theValue,
74                                      std::shared_ptr<PlaneGCSSolver_PointWrapper> thePoint1,
75                                      std::shared_ptr<PlaneGCSSolver_PointWrapper> thePoint2);
76 static ConstraintWrapperPtr
77   createConstraintDistancePointLine(std::shared_ptr<PlaneGCSSolver_ScalarWrapper> theValue,
78                                     std::shared_ptr<PlaneGCSSolver_PointWrapper>  thePoint,
79                                     std::shared_ptr<PlaneGCSSolver_EdgeWrapper> theEntity);
80 static ConstraintWrapperPtr
81   createConstraintHVDistance(const SketchSolver_ConstraintType& theType,
82                              std::shared_ptr<PlaneGCSSolver_ScalarWrapper> theValue,
83                              std::shared_ptr<PlaneGCSSolver_PointWrapper> thePoint1,
84                              std::shared_ptr<PlaneGCSSolver_PointWrapper> thePoint2);
85 static ConstraintWrapperPtr
86   createConstraintRadius(std::shared_ptr<PlaneGCSSolver_ScalarWrapper> theValue,
87                          std::shared_ptr<PlaneGCSSolver_EdgeWrapper> theEntity);
88 static ConstraintWrapperPtr
89   createConstraintAngle(ConstraintPtr theConstraint,
90                         std::shared_ptr<PlaneGCSSolver_ScalarWrapper> theValue,
91                         std::shared_ptr<PlaneGCSSolver_EdgeWrapper> theEntity1,
92                         std::shared_ptr<PlaneGCSSolver_EdgeWrapper> theEntity2);
93 static ConstraintWrapperPtr
94   createConstraintHorizVert(const SketchSolver_ConstraintType& theType,
95                             std::shared_ptr<PlaneGCSSolver_EdgeWrapper> theEntity);
96 static ConstraintWrapperPtr
97   createConstraintParallel(std::shared_ptr<PlaneGCSSolver_EdgeWrapper> theEntity1,
98                            std::shared_ptr<PlaneGCSSolver_EdgeWrapper> theEntity2);
99 static ConstraintWrapperPtr
100   createConstraintPerpendicular(std::shared_ptr<PlaneGCSSolver_EdgeWrapper> theEntity1,
101                                 std::shared_ptr<PlaneGCSSolver_EdgeWrapper> theEntity2);
102 static ConstraintWrapperPtr
103   createConstraintEqual(const SketchSolver_ConstraintType& theType,
104                         std::shared_ptr<PlaneGCSSolver_EdgeWrapper> theEntity1,
105                         std::shared_ptr<PlaneGCSSolver_EdgeWrapper> theEntity2,
106                         std::shared_ptr<PlaneGCSSolver_ScalarWrapper> theIntermed);
107 static ConstraintWrapperPtr
108   createConstraintMiddlePoint(std::shared_ptr<PlaneGCSSolver_PointWrapper> thePoint,
109                               std::shared_ptr<PlaneGCSSolver_EdgeWrapper> theEntity);
110
111 static GCS::SET_pD scalarParameters(const ScalarWrapperPtr& theScalar);
112 static GCS::SET_pD pointParameters(const PointWrapperPtr& thePoint);
113 static GCS::SET_pD lineParameters(const EdgeWrapperPtr& theLine);
114 static GCS::SET_pD circleParameters(const EdgeWrapperPtr& theCircle);
115 static GCS::SET_pD arcParameters(const EdgeWrapperPtr& theArc);
116
117
118
119
120
121 SolverConstraintPtr PlaneGCSSolver_Tools::createConstraint(ConstraintPtr theConstraint)
122 {
123   if (theConstraint->getKind() == SketchPlugin_ConstraintCoincidence::ID()) {
124     return SolverConstraintPtr(new SketchSolver_ConstraintCoincidence(theConstraint));
125   } else if (theConstraint->getKind() == SketchPlugin_ConstraintCollinear::ID()) {
126     return SolverConstraintPtr(new SketchSolver_ConstraintCollinear(theConstraint));
127   } else if (theConstraint->getKind() == SketchPlugin_ConstraintDistance::ID() ||
128              theConstraint->getKind() == SketchPlugin_ConstraintDistanceHorizontal::ID() ||
129              theConstraint->getKind() == SketchPlugin_ConstraintDistanceVertical::ID()) {
130     return SolverConstraintPtr(new SketchSolver_ConstraintDistance(theConstraint));
131   } else if (theConstraint->getKind() == SketchPlugin_ConstraintEqual::ID()) {
132     return SolverConstraintPtr(new SketchSolver_ConstraintEqual(theConstraint));
133   } else if (theConstraint->getKind() == SketchPlugin_ConstraintLength::ID()) {
134     return SolverConstraintPtr(new SketchSolver_ConstraintLength(theConstraint));
135   } else if (theConstraint->getKind() == SketchPlugin_ConstraintMiddle::ID()) {
136     return SolverConstraintPtr(new SketchSolver_ConstraintMiddle(theConstraint));
137   } else if (theConstraint->getKind() == SketchPlugin_ConstraintMirror::ID()) {
138     return SolverConstraintPtr(new SketchSolver_ConstraintMirror(theConstraint));
139   } else if (theConstraint->getKind() == SketchPlugin_ConstraintTangent::ID()) {
140     return SolverConstraintPtr(new SketchSolver_ConstraintTangent(theConstraint));
141   } else if (theConstraint->getKind() == SketchPlugin_ConstraintRigid::ID()) {
142     return SolverConstraintPtr(new SketchSolver_ConstraintFixed(theConstraint));
143   } else if (theConstraint->getKind() == SketchPlugin_MultiTranslation::ID()) {
144     return SolverConstraintPtr(new SketchSolver_ConstraintMultiTranslation(theConstraint));
145   } else if (theConstraint->getKind() == SketchPlugin_MultiRotation::ID()) {
146     return SolverConstraintPtr(new SketchSolver_ConstraintMultiRotation(theConstraint));
147   } else if (theConstraint->getKind() == SketchPlugin_ConstraintAngle::ID()) {
148     return SolverConstraintPtr(new SketchSolver_ConstraintAngle(theConstraint));
149   }
150   // All other types of constraints
151   return SolverConstraintPtr(new SketchSolver_Constraint(theConstraint));
152 }
153
154 std::shared_ptr<SketchSolver_ConstraintMovement> PlaneGCSSolver_Tools::createMovementConstraint(
155     FeaturePtr theMovedFeature)
156 {
157   return std::shared_ptr<SketchSolver_ConstraintMovement>(
158       new SketchSolver_ConstraintMovement(theMovedFeature));
159 }
160
161 std::shared_ptr<SketchSolver_ConstraintMovement> PlaneGCSSolver_Tools::createMovementConstraint(
162     AttributePtr theMovedAttribute)
163 {
164   return std::shared_ptr<SketchSolver_ConstraintMovement>(
165       new SketchSolver_ConstraintMovement(theMovedAttribute));
166 }
167
168
169
170 ConstraintWrapperPtr PlaneGCSSolver_Tools::createConstraint(
171     ConstraintPtr theConstraint,
172     const SketchSolver_ConstraintType& theType,
173     const EntityWrapperPtr& theValue,
174     const EntityWrapperPtr& thePoint1,
175     const EntityWrapperPtr& thePoint2,
176     const EntityWrapperPtr& theEntity1,
177     const EntityWrapperPtr& theEntity2)
178 {
179   ConstraintWrapperPtr aResult;
180   ScalarWrapperPtr anIntermediate;
181
182   std::shared_ptr<PlaneGCSSolver_PointWrapper> aPoint1 = GCS_POINT_WRAPPER(thePoint1);
183   std::shared_ptr<PlaneGCSSolver_PointWrapper> aPoint2 = GCS_POINT_WRAPPER(thePoint2);
184
185   switch (theType) {
186   case CONSTRAINT_PT_PT_COINCIDENT:
187     aResult = createConstraintCoincidence(aPoint1, aPoint2);
188     break;
189   case CONSTRAINT_PT_ON_LINE:
190   case CONSTRAINT_PT_ON_CIRCLE:
191     aResult = createConstraintPointOnEntity(theType, aPoint1, GCS_EDGE_WRAPPER(theEntity1));
192     break;
193   case CONSTRAINT_MIDDLE_POINT:
194     aResult = createConstraintMiddlePoint(aPoint1, GCS_EDGE_WRAPPER(theEntity1));
195     break;
196   case CONSTRAINT_PT_PT_DISTANCE:
197     aResult = createConstraintDistancePointPoint(GCS_SCALAR_WRAPPER(theValue), aPoint1, aPoint2);
198     break;
199   case CONSTRAINT_PT_LINE_DISTANCE:
200     aResult = createConstraintDistancePointLine(GCS_SCALAR_WRAPPER(theValue),
201                                                 aPoint1,
202                                                 GCS_EDGE_WRAPPER(theEntity1));
203     break;
204   case CONSTRAINT_HORIZONTAL_DISTANCE:
205   case CONSTRAINT_VERTICAL_DISTANCE:
206     aResult = createConstraintHVDistance(theType, GCS_SCALAR_WRAPPER(theValue), aPoint1, aPoint2);
207     break;
208   case CONSTRAINT_RADIUS:
209     aResult = createConstraintRadius(GCS_SCALAR_WRAPPER(theValue),
210                                      GCS_EDGE_WRAPPER(theEntity1));
211     break;
212   case CONSTRAINT_ANGLE:
213     aResult = createConstraintAngle(theConstraint,
214                   GCS_SCALAR_WRAPPER(theValue),
215                   GCS_EDGE_WRAPPER(theEntity1), GCS_EDGE_WRAPPER(theEntity2));
216     break;
217   case CONSTRAINT_FIXED:
218     break;
219   case CONSTRAINT_HORIZONTAL:
220   case CONSTRAINT_VERTICAL:
221     aResult = createConstraintHorizVert(theType, GCS_EDGE_WRAPPER(theEntity1));
222     break;
223   case CONSTRAINT_PARALLEL:
224     aResult = createConstraintParallel(GCS_EDGE_WRAPPER(theEntity1),
225                                        GCS_EDGE_WRAPPER(theEntity2));
226     break;
227   case CONSTRAINT_PERPENDICULAR:
228     aResult = createConstraintPerpendicular(GCS_EDGE_WRAPPER(theEntity1),
229                                             GCS_EDGE_WRAPPER(theEntity2));
230     break;
231   case CONSTRAINT_EQUAL_LINES:
232     anIntermediate = GCS_SCALAR_WRAPPER(theValue); // parameter is used to store length of lines
233   case CONSTRAINT_EQUAL_LINE_ARC:
234   case CONSTRAINT_EQUAL_RADIUS:
235     aResult = createConstraintEqual(theType,
236                                     GCS_EDGE_WRAPPER(theEntity1),
237                                     GCS_EDGE_WRAPPER(theEntity2),
238                                     anIntermediate);
239     break;
240   default:
241     break;
242   }
243
244   return aResult;
245 }
246
247 std::shared_ptr<GeomAPI_Pnt2d> PlaneGCSSolver_Tools::point(EntityWrapperPtr theEntity)
248 {
249   if (theEntity->type() != ENTITY_POINT)
250     return std::shared_ptr<GeomAPI_Pnt2d>();
251
252   std::shared_ptr<PlaneGCSSolver_PointWrapper> aPointWrapper =
253       std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(theEntity);
254   const GCSPointPtr& aPoint = aPointWrapper->point();
255   return std::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(*aPoint->x, *aPoint->y));
256 }
257
258 std::shared_ptr<GeomAPI_Lin2d> PlaneGCSSolver_Tools::line(EntityWrapperPtr theEntity)
259 {
260   if (theEntity->type() != ENTITY_LINE)
261     return std::shared_ptr<GeomAPI_Lin2d>();
262
263   std::shared_ptr<PlaneGCSSolver_EdgeWrapper> anEntity =
264       std::dynamic_pointer_cast<PlaneGCSSolver_EdgeWrapper>(theEntity);
265   std::shared_ptr<GCS::Line> aLine = std::dynamic_pointer_cast<GCS::Line>(anEntity->entity());
266   return std::shared_ptr<GeomAPI_Lin2d>(
267       new GeomAPI_Lin2d(*(aLine->p1.x), *(aLine->p1.y), *(aLine->p2.x), *(aLine->p2.y)));
268 }
269
270 std::shared_ptr<GeomAPI_Lin2d> PlaneGCSSolver_Tools::line(FeaturePtr theFeature)
271 {
272   if (theFeature->getKind() != SketchPlugin_Line::ID())
273     return std::shared_ptr<GeomAPI_Lin2d>();
274
275   AttributePoint2DPtr aStart = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
276       theFeature->attribute(SketchPlugin_Line::START_ID()));
277   AttributePoint2DPtr aEnd = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
278       theFeature->attribute(SketchPlugin_Line::END_ID()));
279
280   return std::shared_ptr<GeomAPI_Lin2d>(new GeomAPI_Lin2d(aStart->pnt(), aEnd->pnt()));
281 }
282
283
284 GCS::SET_pD PlaneGCSSolver_Tools::parameters(const EntityWrapperPtr& theEntity)
285 {
286   switch (theEntity->type()) {
287   case ENTITY_SCALAR:
288   case ENTITY_ANGLE:
289     return scalarParameters(GCS_SCALAR_WRAPPER(theEntity));
290   case ENTITY_POINT:
291     return pointParameters(GCS_POINT_WRAPPER(theEntity));
292   case ENTITY_LINE:
293     return lineParameters(GCS_EDGE_WRAPPER(theEntity));
294   case ENTITY_CIRCLE:
295     return circleParameters(GCS_EDGE_WRAPPER(theEntity));
296   case ENTITY_ARC:
297     return arcParameters(GCS_EDGE_WRAPPER(theEntity));
298   default: break;
299   }
300   return GCS::SET_pD();
301 }
302
303
304
305
306
307
308 // ================   Auxiliary functions   ==========================
309 ConstraintWrapperPtr createConstraintCoincidence(
310     std::shared_ptr<PlaneGCSSolver_PointWrapper> thePoint1,
311     std::shared_ptr<PlaneGCSSolver_PointWrapper> thePoint2)
312 {
313   GCSPointPtr aPoint1 = thePoint1->point();
314   GCSPointPtr aPoint2 = thePoint2->point();
315
316   // Create equality constraint for corresponding attributes of the points
317   std::list<GCSConstraintPtr> aConstrList;
318   aConstrList.push_back(
319       GCSConstraintPtr(new GCS::ConstraintEqual(aPoint1->x, aPoint2->x)));
320   aConstrList.push_back(
321       GCSConstraintPtr(new GCS::ConstraintEqual(aPoint1->y, aPoint2->y)));
322
323   return ConstraintWrapperPtr(new PlaneGCSSolver_ConstraintWrapper(
324       aConstrList, CONSTRAINT_PT_PT_COINCIDENT));
325 }
326
327 ConstraintWrapperPtr createConstraintPointOnEntity(
328     const SketchSolver_ConstraintType& theType,
329     std::shared_ptr<PlaneGCSSolver_PointWrapper> thePoint,
330     std::shared_ptr<PlaneGCSSolver_EdgeWrapper> theEntity)
331 {
332   GCSConstraintPtr aNewConstr;
333
334   switch (theEntity->type()) {
335   case ENTITY_LINE: {
336     std::shared_ptr<GCS::Line> aLine = std::dynamic_pointer_cast<GCS::Line>(theEntity->entity());
337     aNewConstr = GCSConstraintPtr(new GCS::ConstraintPointOnLine(*(thePoint->point()), *aLine));
338     break;
339     }
340   case ENTITY_ARC:
341   case ENTITY_CIRCLE: {
342     std::shared_ptr<GCS::Circle> aCirc =
343       std::dynamic_pointer_cast<GCS::Circle>(theEntity->entity());
344     aNewConstr = GCSConstraintPtr(
345         new GCS::ConstraintP2PDistance(*(thePoint->point()), aCirc->center, aCirc->rad));
346     break;
347     }
348   default:
349     return ConstraintWrapperPtr();
350   }
351
352   return ConstraintWrapperPtr(new PlaneGCSSolver_ConstraintWrapper(aNewConstr, theType));
353 }
354
355 ConstraintWrapperPtr createConstraintMiddlePoint(
356     std::shared_ptr<PlaneGCSSolver_PointWrapper> thePoint,
357     std::shared_ptr<PlaneGCSSolver_EdgeWrapper> theEntity)
358 {
359   GCSPointPtr aPoint = thePoint->point();
360   std::shared_ptr<GCS::Line> aLine = std::dynamic_pointer_cast<GCS::Line>(theEntity->entity());
361   if (!aLine)
362     return ConstraintWrapperPtr();
363
364   std::list<GCSConstraintPtr> aConstrList;
365   aConstrList.push_back(
366       GCSConstraintPtr(new GCS::ConstraintPointOnPerpBisector(*aPoint, aLine->p1, aLine->p2)));
367   aConstrList.push_back(GCSConstraintPtr(new GCS::ConstraintPointOnLine(*aPoint, *aLine)));
368
369   return ConstraintWrapperPtr(
370       new PlaneGCSSolver_ConstraintWrapper(aConstrList, CONSTRAINT_MIDDLE_POINT));
371 }
372
373
374 ConstraintWrapperPtr createConstraintDistancePointPoint(
375     std::shared_ptr<PlaneGCSSolver_ScalarWrapper> theValue,
376     std::shared_ptr<PlaneGCSSolver_PointWrapper>  thePoint1,
377     std::shared_ptr<PlaneGCSSolver_PointWrapper>  thePoint2)
378 {
379   GCSConstraintPtr aNewConstr(new GCS::ConstraintP2PDistance(
380       *(thePoint1->point()), *(thePoint2->point()), theValue->scalar()));
381   std::shared_ptr<PlaneGCSSolver_ConstraintWrapper> aResult(
382       new PlaneGCSSolver_ConstraintWrapper(aNewConstr, CONSTRAINT_PT_PT_DISTANCE));
383   aResult->setValueParameter(theValue);
384   return aResult;
385 }
386
387 ConstraintWrapperPtr createConstraintDistancePointLine(
388     std::shared_ptr<PlaneGCSSolver_ScalarWrapper> theValue,
389     std::shared_ptr<PlaneGCSSolver_PointWrapper>  thePoint,
390     std::shared_ptr<PlaneGCSSolver_EdgeWrapper> theEntity)
391 {
392   std::shared_ptr<GCS::Line> aLine = std::dynamic_pointer_cast<GCS::Line>(theEntity->entity());
393   GCSConstraintPtr aNewConstr(new GCS::ConstraintP2LDistance(
394       *(thePoint->point()), *(aLine), theValue->scalar()));
395   std::shared_ptr<PlaneGCSSolver_ConstraintWrapper> aResult(
396       new PlaneGCSSolver_ConstraintWrapper(aNewConstr, CONSTRAINT_PT_LINE_DISTANCE));
397   aResult->setValueParameter(theValue);
398   return aResult;
399 }
400
401 ConstraintWrapperPtr createConstraintHVDistance(
402     const SketchSolver_ConstraintType& theType,
403     std::shared_ptr<PlaneGCSSolver_ScalarWrapper> theValue,
404     std::shared_ptr<PlaneGCSSolver_PointWrapper> thePoint1,
405     std::shared_ptr<PlaneGCSSolver_PointWrapper> thePoint2)
406 {
407   GCSPointPtr aPoint1 = thePoint1->point();
408   GCSPointPtr aPoint2 = thePoint2->point();
409
410   double *aParam1, *aParam2;
411   if (theType == CONSTRAINT_HORIZONTAL_DISTANCE) {
412     aParam1 = aPoint1->x;
413     aParam2 = aPoint2->x;
414   } else if (theType == CONSTRAINT_VERTICAL_DISTANCE) {
415     aParam1 = aPoint1->y;
416     aParam2 = aPoint2->y;
417   }
418
419   GCSConstraintPtr aNewConstr(new GCS::ConstraintDifference(aParam1, aParam2, theValue->scalar()));
420
421   std::shared_ptr<PlaneGCSSolver_ConstraintWrapper> aResult(
422       new PlaneGCSSolver_ConstraintWrapper(aNewConstr, theType));
423   aResult->setValueParameter(theValue);
424   return aResult;
425 }
426
427 ConstraintWrapperPtr createConstraintRadius(
428     std::shared_ptr<PlaneGCSSolver_ScalarWrapper> theValue,
429     std::shared_ptr<PlaneGCSSolver_EdgeWrapper> theEntity)
430 {
431   std::shared_ptr<GCS::Circle> aCircle =
432     std::dynamic_pointer_cast<GCS::Circle>(theEntity->entity());
433   GCSConstraintPtr aNewConstr(new GCS::ConstraintEqual(aCircle->rad, theValue->scalar()));
434   std::shared_ptr<PlaneGCSSolver_ConstraintWrapper> aResult(
435       new PlaneGCSSolver_ConstraintWrapper(aNewConstr, CONSTRAINT_RADIUS));
436   aResult->setValueParameter(theValue);
437   return aResult;
438 }
439
440 ConstraintWrapperPtr createConstraintAngle(
441     ConstraintPtr theConstraint,
442     std::shared_ptr<PlaneGCSSolver_ScalarWrapper> theValue,
443     std::shared_ptr<PlaneGCSSolver_EdgeWrapper> theEntity1,
444     std::shared_ptr<PlaneGCSSolver_EdgeWrapper> theEntity2)
445 {
446   std::shared_ptr<GCS::Line> aLine1 = std::dynamic_pointer_cast<GCS::Line>(theEntity1->entity());
447   bool isLine1Rev = theConstraint->boolean(
448       SketchPlugin_ConstraintAngle::ANGLE_REVERSED_FIRST_LINE_ID())->value();
449   GCS::Point aLine1Pt1 = isLine1Rev ? aLine1->p2 : aLine1->p1;
450   GCS::Point aLine1Pt2 = isLine1Rev ? aLine1->p1 : aLine1->p2;
451
452   std::shared_ptr<GCS::Line> aLine2 = std::dynamic_pointer_cast<GCS::Line>(theEntity2->entity());
453   bool isLine2Rev = theConstraint->boolean(
454       SketchPlugin_ConstraintAngle::ANGLE_REVERSED_SECOND_LINE_ID())->value();
455   GCS::Point aLine2Pt1 = isLine2Rev ? aLine2->p2 : aLine2->p1;
456   GCS::Point aLine2Pt2 = isLine2Rev ? aLine2->p1 : aLine2->p2;
457
458   GCSConstraintPtr aNewConstr(new GCS::ConstraintL2LAngle(
459       aLine1Pt1, aLine1Pt2, aLine2Pt1, aLine2Pt2, theValue->scalar()));
460
461   std::shared_ptr<PlaneGCSSolver_ConstraintWrapper> aResult(
462       new PlaneGCSSolver_ConstraintWrapper(aNewConstr, CONSTRAINT_ANGLE));
463   aResult->setValueParameter(theValue);
464   return aResult;
465 }
466
467 ConstraintWrapperPtr createConstraintHorizVert(
468     const SketchSolver_ConstraintType& theType,
469     std::shared_ptr<PlaneGCSSolver_EdgeWrapper> theEntity)
470 {
471   std::shared_ptr<GCS::Line> aLine = std::dynamic_pointer_cast<GCS::Line>(theEntity->entity());
472   GCSConstraintPtr aNewConstr;
473   if (theType == CONSTRAINT_HORIZONTAL)
474     aNewConstr = GCSConstraintPtr(new GCS::ConstraintEqual(aLine->p1.y, aLine->p2.y));
475   else
476     aNewConstr = GCSConstraintPtr(new GCS::ConstraintEqual(aLine->p1.x, aLine->p2.x));
477
478   return ConstraintWrapperPtr(new PlaneGCSSolver_ConstraintWrapper(aNewConstr, theType));
479 }
480
481 ConstraintWrapperPtr createConstraintParallel(
482     std::shared_ptr<PlaneGCSSolver_EdgeWrapper> theEntity1,
483     std::shared_ptr<PlaneGCSSolver_EdgeWrapper> theEntity2)
484 {
485   std::shared_ptr<GCS::Line> aLine1 = std::dynamic_pointer_cast<GCS::Line>(theEntity1->entity());
486   std::shared_ptr<GCS::Line> aLine2 = std::dynamic_pointer_cast<GCS::Line>(theEntity2->entity());
487   GCSConstraintPtr aNewConstr(new GCS::ConstraintParallel(*(aLine1), *(aLine2)));
488
489   return ConstraintWrapperPtr(
490       new PlaneGCSSolver_ConstraintWrapper(aNewConstr, CONSTRAINT_PARALLEL));
491 }
492
493 ConstraintWrapperPtr createConstraintPerpendicular(
494     std::shared_ptr<PlaneGCSSolver_EdgeWrapper> theEntity1,
495     std::shared_ptr<PlaneGCSSolver_EdgeWrapper> theEntity2)
496 {
497   std::shared_ptr<GCS::Line> aLine1 = std::dynamic_pointer_cast<GCS::Line>(theEntity1->entity());
498   std::shared_ptr<GCS::Line> aLine2 = std::dynamic_pointer_cast<GCS::Line>(theEntity2->entity());
499   GCSConstraintPtr aNewConstr(new GCS::ConstraintPerpendicular(*(aLine1), *(aLine2)));
500
501   return ConstraintWrapperPtr(
502       new PlaneGCSSolver_ConstraintWrapper(aNewConstr, CONSTRAINT_PERPENDICULAR));
503 }
504
505 ConstraintWrapperPtr createConstraintEqual(
506     const SketchSolver_ConstraintType& theType,
507     std::shared_ptr<PlaneGCSSolver_EdgeWrapper> theEntity1,
508     std::shared_ptr<PlaneGCSSolver_EdgeWrapper> theEntity2,
509     std::shared_ptr<PlaneGCSSolver_ScalarWrapper> theIntermed)
510 {
511   if (theType == CONSTRAINT_EQUAL_LINE_ARC)
512     return ConstraintWrapperPtr(); // line-arc equivalence is not supported yet
513
514   std::list<GCSConstraintPtr> aConstrList;
515   if (theType == CONSTRAINT_EQUAL_LINES) {
516     std::shared_ptr<GCS::Line> aLine1 = std::dynamic_pointer_cast<GCS::Line>(theEntity1->entity());
517     std::shared_ptr<GCS::Line> aLine2 = std::dynamic_pointer_cast<GCS::Line>(theEntity2->entity());
518
519     aConstrList.push_back(GCSConstraintPtr(
520         new GCS::ConstraintP2PDistance(aLine1->p1, aLine1->p2, theIntermed->scalar())));
521     aConstrList.push_back(GCSConstraintPtr(
522         new GCS::ConstraintP2PDistance(aLine2->p1, aLine2->p2, theIntermed->scalar())));
523     // update value of intermediate parameter
524     double x = *aLine1->p1.x - *aLine1->p2.x;
525     double y = *aLine1->p1.y - *aLine1->p2.y;
526     double aLen = sqrt(x*x + y*y);
527     theIntermed->setValue(aLen);
528   } else {
529     std::shared_ptr<GCS::Circle> aCirc1 =
530         std::dynamic_pointer_cast<GCS::Circle>(theEntity1->entity());
531     std::shared_ptr<GCS::Circle> aCirc2 =
532         std::dynamic_pointer_cast<GCS::Circle>(theEntity2->entity());
533
534     aConstrList.push_back(GCSConstraintPtr(new GCS::ConstraintEqual(aCirc1->rad, aCirc2->rad)));
535   }
536
537   std::shared_ptr<PlaneGCSSolver_ConstraintWrapper> aResult(
538       new PlaneGCSSolver_ConstraintWrapper(aConstrList, theType));
539   if (theIntermed)
540     aResult->setValueParameter(theIntermed);
541   return aResult;
542 }
543
544 GCS::SET_pD scalarParameters(const ScalarWrapperPtr& theScalar)
545 {
546   GCS::SET_pD aParams;
547   aParams.insert(theScalar->scalar());
548   return aParams;
549 }
550
551 GCS::SET_pD pointParameters(const PointWrapperPtr& thePoint)
552 {
553   GCS::SET_pD aParams;
554   aParams.insert(thePoint->point()->x);
555   aParams.insert(thePoint->point()->y);
556   return aParams;
557 }
558
559 GCS::SET_pD lineParameters(const EdgeWrapperPtr& theLine)
560 {
561   GCS::SET_pD aParams;
562   std::shared_ptr<GCS::Line> aLine = std::dynamic_pointer_cast<GCS::Line>(theLine->entity());
563   aParams.insert(aLine->p1.x);
564   aParams.insert(aLine->p1.y);
565   aParams.insert(aLine->p2.x);
566   aParams.insert(aLine->p2.y);
567   return aParams;
568 }
569
570 GCS::SET_pD circleParameters(const EdgeWrapperPtr& theCircle)
571 {
572   GCS::SET_pD aParams;
573   std::shared_ptr<GCS::Circle> aCirc = std::dynamic_pointer_cast<GCS::Circle>(theCircle->entity());
574   aParams.insert(aCirc->center.x);
575   aParams.insert(aCirc->center.y);
576   aParams.insert(aCirc->rad);
577   return aParams;
578 }
579
580 GCS::SET_pD arcParameters(const EdgeWrapperPtr& theArc)
581 {
582   GCS::SET_pD aParams;
583   std::shared_ptr<GCS::Arc> anArc = std::dynamic_pointer_cast<GCS::Arc>(theArc->entity());
584   aParams.insert(anArc->center.x);
585   aParams.insert(anArc->center.y);
586   aParams.insert(anArc->start.x);
587   aParams.insert(anArc->start.y);
588   aParams.insert(anArc->end.x);
589   aParams.insert(anArc->end.y);
590   aParams.insert(anArc->startAngle);
591   aParams.insert(anArc->endAngle);
592   aParams.insert(anArc->rad);
593   return aParams;
594 }