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