]> SALOME platform Git repositories - modules/shaper.git/blob - src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_FeatureBuilder.cpp
Salome HOME
SketchSolver Refactoring: Eliminate SolveSpace as a sketch solver.
[modules/shaper.git] / src / SketchSolver / PlaneGCSSolver / PlaneGCSSolver_FeatureBuilder.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
2
3 // File:    PlaneGCSSolver_AttributeBuilder.cpp
4 // Created: 10 Feb 2017
5 // Author:  Artem ZHIDKOV
6
7 #include <PlaneGCSSolver_FeatureBuilder.h>
8 #include <PlaneGCSSolver_EntityWrapper.h>
9 #include <PlaneGCSSolver_PointWrapper.h>
10 #include <PlaneGCSSolver_ScalarWrapper.h>
11
12 #include <SketchPlugin_Arc.h>
13 #include <SketchPlugin_Circle.h>
14 #include <SketchPlugin_IntersectionPoint.h>
15 #include <SketchPlugin_Line.h>
16 #include <SketchPlugin_Point.h>
17
18 #include <GeomAPI_Dir2d.h>
19 #include <GeomAPI_Pnt2d.h>
20 #include <GeomAPI_XY.h>
21
22 static EntityWrapperPtr createLine(const AttributeEntityMap& theAttributes);
23 static EntityWrapperPtr createCircle(const AttributeEntityMap& theAttributes);
24 static EntityWrapperPtr createArc(const AttributeEntityMap&    theAttributes,
25                                   PlaneGCSSolver_Storage*      theStorage,
26                                   std::list<GCSConstraintPtr>& theArcConstraints);
27
28
29 PlaneGCSSolver_FeatureBuilder::PlaneGCSSolver_FeatureBuilder(
30     PlaneGCSSolver_Storage* theStorage)
31   : PlaneGCSSolver_AttributeBuilder(theStorage)
32 {
33 }
34
35 PlaneGCSSolver_FeatureBuilder::PlaneGCSSolver_FeatureBuilder(const StoragePtr& theStorage)
36   : PlaneGCSSolver_AttributeBuilder(theStorage)
37 {
38 }
39
40 EntityWrapperPtr PlaneGCSSolver_FeatureBuilder::createAttribute(
41     AttributePtr theAttribute)
42 {
43   EntityWrapperPtr anAttr = PlaneGCSSolver_AttributeBuilder::createAttribute(theAttribute);
44   if (anAttr)
45     myAttributes[theAttribute] = anAttr;
46   return anAttr;
47 }
48
49 EntityWrapperPtr PlaneGCSSolver_FeatureBuilder::createFeature(FeaturePtr theFeature)
50 {
51   EntityWrapperPtr aResult;
52   if (myStorage)
53     aResult = myStorage->entity(theFeature);
54   if (aResult)
55     return aResult;
56
57   // Process SketchPlugin features only
58   std::shared_ptr<SketchPlugin_Feature> aFeature =
59       std::dynamic_pointer_cast<SketchPlugin_Feature>(theFeature);
60   if (!aFeature)
61     return aResult;
62
63   // Verify the feature by its kind
64   const std::string& aFeatureKind = aFeature->getKind();
65   // Line
66   if (aFeatureKind == SketchPlugin_Line::ID())
67     aResult = createLine(myAttributes);
68   // Circle
69   else if (aFeatureKind == SketchPlugin_Circle::ID())
70     aResult = createCircle(myAttributes);
71   // Arc
72   else if (aFeatureKind == SketchPlugin_Arc::ID())
73     aResult = createArc(myAttributes, myStorage, myFeatureConstraints);
74   // Point (it has low probability to be an attribute of constraint, so it is checked at the end)
75   else if (aFeatureKind == SketchPlugin_Point::ID() ||
76            aFeatureKind == SketchPlugin_IntersectionPoint::ID()) {
77     AttributeEntityMap::const_iterator anIt = myAttributes.begin();
78     for (; anIt != myAttributes.end(); ++anIt)
79       if (anIt->first->id() == SketchPlugin_Point::COORD_ID()) {
80         aResult = anIt->second;
81         break;
82       }
83   }
84
85   if (aResult && !myStorage)
86     aResult->setExternal(true);
87
88   myAttributes.clear();
89   return aResult;
90 }
91
92
93
94
95
96 // ==============   Auxiliary functions   =====================================
97 EntityWrapperPtr createLine(const AttributeEntityMap& theAttributes)
98 {
99   std::shared_ptr<GCS::Line> aNewLine(new GCS::Line);
100
101   AttributeEntityMap::const_iterator anIt = theAttributes.begin();
102   for (; anIt != theAttributes.end(); ++anIt) {
103     std::shared_ptr<PlaneGCSSolver_PointWrapper> aPoint =
104         std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(anIt->second);
105     if (!aPoint)
106       continue;
107
108     if (anIt->first->id() == SketchPlugin_Line::START_ID())
109       aNewLine->p1 = *(aPoint->point());
110     else if (anIt->first->id() == SketchPlugin_Line::END_ID())
111       aNewLine->p2 = *(aPoint->point());
112   }
113
114   return EntityWrapperPtr(new PlaneGCSSolver_EntityWrapper(aNewLine));
115 }
116
117 EntityWrapperPtr createCircle(const AttributeEntityMap& theAttributes)
118 {
119   std::shared_ptr<GCS::Circle> aNewCircle(new GCS::Circle);
120
121   AttributeEntityMap::const_iterator anIt = theAttributes.begin();
122   for (; anIt != theAttributes.end(); ++anIt) {
123     if (anIt->first->id() == SketchPlugin_Circle::CENTER_ID()) {
124       std::shared_ptr<PlaneGCSSolver_PointWrapper> aPoint =
125           std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(anIt->second);
126       aNewCircle->center = *(aPoint->point());
127     }
128     else if(anIt->first->id() == SketchPlugin_Circle::RADIUS_ID()) {
129       ScalarWrapperPtr aScalar =
130           std::dynamic_pointer_cast<PlaneGCSSolver_ScalarWrapper>(anIt->second);
131       aNewCircle->rad = aScalar->scalar();
132     }
133   }
134
135   return EntityWrapperPtr(new PlaneGCSSolver_EntityWrapper(aNewCircle));
136 }
137
138 static double* createParameter(PlaneGCSSolver_Storage* theStorage)
139 {
140   return theStorage ? theStorage->createParameter() : (new double(0));
141 }
142
143 EntityWrapperPtr createArc(const AttributeEntityMap&    theAttributes,
144                            PlaneGCSSolver_Storage*      theStorage,
145                            std::list<GCSConstraintPtr>& theArcConstraints)
146 {
147   std::shared_ptr<GCS::Arc> aNewArc(new GCS::Arc);
148
149   // Base attributes of arc (center, start and end points)
150   AttributeEntityMap::const_iterator anIt = theAttributes.begin();
151   for (; anIt != theAttributes.end(); ++anIt) {
152     std::shared_ptr<PlaneGCSSolver_PointWrapper> aPoint =
153         std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(anIt->second);
154     if (!aPoint)
155       continue;
156
157     if (anIt->first->id() == SketchPlugin_Arc::CENTER_ID())
158       aNewArc->center = *(aPoint->point());
159     else if (anIt->first->id() == SketchPlugin_Arc::START_ID())
160       aNewArc->start = *(aPoint->point());
161     else if (anIt->first->id() == SketchPlugin_Arc::END_ID())
162       aNewArc->end = *(aPoint->point());
163   }
164
165   // Additional atrtributes of arc necessary for PlaneGCS solver
166   // (start and end angles, radius)
167   aNewArc->startAngle = createParameter(theStorage);
168   aNewArc->endAngle   = createParameter(theStorage);
169   aNewArc->rad        = createParameter(theStorage);
170
171   static std::shared_ptr<GeomAPI_Dir2d> OX(new GeomAPI_Dir2d(1.0, 0.0));
172   std::shared_ptr<GeomAPI_Pnt2d> aCenter(
173       new GeomAPI_Pnt2d(*aNewArc->center.x, *aNewArc->center.y));
174   std::shared_ptr<GeomAPI_Pnt2d> aStart(
175       new GeomAPI_Pnt2d(*aNewArc->start.x, *aNewArc->start.y));
176
177   *aNewArc->rad = aStart->distance(aCenter);
178
179   std::shared_ptr<GeomAPI_Dir2d> aDir(new GeomAPI_Dir2d(aStart->xy()->decreased(aCenter->xy())));
180   *aNewArc->startAngle = OX->angle(aDir);
181
182   aDir = std::shared_ptr<GeomAPI_Dir2d>(
183       new GeomAPI_Dir2d((*aNewArc->end.x) - aCenter->x(), (*aNewArc->end.y) - aCenter->y()));
184   *aNewArc->endAngle = OX->angle(aDir);
185
186   if (theStorage) {
187     // Additional constaints to fix arc's extra DoF (if the arc is not external):
188     // 1. distances from center till start and end points are equal to radius
189     theArcConstraints.push_back(GCSConstraintPtr(new GCS::ConstraintP2PDistance(
190         aNewArc->center, aNewArc->start, aNewArc->rad)));
191     theArcConstraints.push_back(GCSConstraintPtr(new GCS::ConstraintP2PDistance(
192         aNewArc->center, aNewArc->end, aNewArc->rad)));
193     // 2. angles of start and end points should be equal to the arc angles
194     theArcConstraints.push_back(GCSConstraintPtr(new GCS::ConstraintP2PAngle(
195         aNewArc->center, aNewArc->start, aNewArc->startAngle)));
196     theArcConstraints.push_back(GCSConstraintPtr(new GCS::ConstraintP2PAngle(
197         aNewArc->center, aNewArc->end, aNewArc->endAngle)));
198   }
199
200   return EntityWrapperPtr(new PlaneGCSSolver_EntityWrapper(aNewArc));
201 }