Salome HOME
Fix incorrect processing of the copied entities after the "Multi" constraint has...
[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_EdgeWrapper.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 bool isAttributeApplicable(const std::string& theAttrName,
23                                   const std::string& theOwnerName);
24
25 static EntityWrapperPtr createLine(const AttributeEntityMap& theAttributes);
26 static EntityWrapperPtr createCircle(const AttributeEntityMap& theAttributes);
27 static EntityWrapperPtr createArc(const AttributeEntityMap&    theAttributes,
28                                   PlaneGCSSolver_Storage*      theStorage);
29
30
31 PlaneGCSSolver_FeatureBuilder::PlaneGCSSolver_FeatureBuilder(
32     PlaneGCSSolver_Storage* theStorage)
33   : PlaneGCSSolver_AttributeBuilder(theStorage)
34 {
35 }
36
37 PlaneGCSSolver_FeatureBuilder::PlaneGCSSolver_FeatureBuilder(const StoragePtr& theStorage)
38   : PlaneGCSSolver_AttributeBuilder(theStorage)
39 {
40 }
41
42 EntityWrapperPtr PlaneGCSSolver_FeatureBuilder::createAttribute(
43     AttributePtr theAttribute)
44 {
45   FeaturePtr anOwner = ModelAPI_Feature::feature(theAttribute->owner());
46   EntityWrapperPtr anAttr;
47   if (isAttributeApplicable(theAttribute->id(), anOwner->getKind()))
48     anAttr = PlaneGCSSolver_AttributeBuilder::createAttribute(theAttribute);
49   if (anAttr)
50     myAttributes[theAttribute] = anAttr;
51   return anAttr;
52 }
53
54 EntityWrapperPtr PlaneGCSSolver_FeatureBuilder::createFeature(FeaturePtr theFeature)
55 {
56   EntityWrapperPtr aResult;
57   if (myStorage)
58     aResult = myStorage->entity(theFeature);
59   if (aResult)
60     return aResult;
61
62   // Process SketchPlugin features only
63   std::shared_ptr<SketchPlugin_Feature> aFeature =
64       std::dynamic_pointer_cast<SketchPlugin_Feature>(theFeature);
65   if (!aFeature)
66     return aResult;
67
68   // Verify the feature by its kind
69   const std::string& aFeatureKind = aFeature->getKind();
70   // Line
71   if (aFeatureKind == SketchPlugin_Line::ID())
72     aResult = createLine(myAttributes);
73   // Circle
74   else if (aFeatureKind == SketchPlugin_Circle::ID())
75     aResult = createCircle(myAttributes);
76   // Arc
77   else if (aFeatureKind == SketchPlugin_Arc::ID())
78     aResult = createArc(myAttributes, myStorage);
79   // Point (it has low probability to be an attribute of constraint, so it is checked at the end)
80   else if (aFeatureKind == SketchPlugin_Point::ID() ||
81            aFeatureKind == SketchPlugin_IntersectionPoint::ID()) {
82     AttributeEntityMap::const_iterator anIt = myAttributes.begin();
83     for (; anIt != myAttributes.end(); ++anIt)
84       if (anIt->first->id() == SketchPlugin_Point::COORD_ID()) {
85         aResult = anIt->second;
86         break;
87       }
88   }
89
90   if (aResult && !myStorage)
91     aResult->setExternal(true);
92
93   myAttributes.clear();
94   return aResult;
95 }
96
97
98
99
100
101 // ==============   Auxiliary functions   =====================================
102 EntityWrapperPtr createLine(const AttributeEntityMap& theAttributes)
103 {
104   std::shared_ptr<GCS::Line> aNewLine(new GCS::Line);
105
106   AttributeEntityMap::const_iterator anIt = theAttributes.begin();
107   for (; anIt != theAttributes.end(); ++anIt) {
108     std::shared_ptr<PlaneGCSSolver_PointWrapper> aPoint =
109         std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(anIt->second);
110     if (!aPoint)
111       continue;
112
113     if (anIt->first->id() == SketchPlugin_Line::START_ID())
114       aNewLine->p1 = *(aPoint->point());
115     else if (anIt->first->id() == SketchPlugin_Line::END_ID())
116       aNewLine->p2 = *(aPoint->point());
117   }
118
119   return EntityWrapperPtr(new PlaneGCSSolver_EdgeWrapper(aNewLine));
120 }
121
122 EntityWrapperPtr createCircle(const AttributeEntityMap& theAttributes)
123 {
124   std::shared_ptr<GCS::Circle> aNewCircle(new GCS::Circle);
125
126   AttributeEntityMap::const_iterator anIt = theAttributes.begin();
127   for (; anIt != theAttributes.end(); ++anIt) {
128     if (anIt->first->id() == SketchPlugin_Circle::CENTER_ID()) {
129       std::shared_ptr<PlaneGCSSolver_PointWrapper> aPoint =
130           std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(anIt->second);
131       aNewCircle->center = *(aPoint->point());
132     }
133     else if(anIt->first->id() == SketchPlugin_Circle::RADIUS_ID()) {
134       ScalarWrapperPtr aScalar =
135           std::dynamic_pointer_cast<PlaneGCSSolver_ScalarWrapper>(anIt->second);
136       aNewCircle->rad = aScalar->scalar();
137     }
138   }
139
140   return EntityWrapperPtr(new PlaneGCSSolver_EdgeWrapper(aNewCircle));
141 }
142
143 static double* createParameter(PlaneGCSSolver_Storage* theStorage)
144 {
145   return theStorage ? theStorage->createParameter() : (new double(0));
146 }
147
148 EntityWrapperPtr createArc(const AttributeEntityMap&    theAttributes,
149                            PlaneGCSSolver_Storage*      theStorage)
150 {
151   std::shared_ptr<GCS::Arc> aNewArc(new GCS::Arc);
152
153   // Base attributes of arc (center, start and end points)
154   AttributeEntityMap::const_iterator anIt = theAttributes.begin();
155   for (; anIt != theAttributes.end(); ++anIt) {
156     std::shared_ptr<PlaneGCSSolver_PointWrapper> aPoint =
157         std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(anIt->second);
158     if (!aPoint)
159       continue;
160
161     if (anIt->first->id() == SketchPlugin_Arc::CENTER_ID())
162       aNewArc->center = *(aPoint->point());
163     else if (anIt->first->id() == SketchPlugin_Arc::START_ID())
164       aNewArc->start = *(aPoint->point());
165     else if (anIt->first->id() == SketchPlugin_Arc::END_ID())
166       aNewArc->end = *(aPoint->point());
167   }
168
169   // Additional atrtributes of arc necessary for PlaneGCS solver
170   // (start and end angles, radius)
171   aNewArc->startAngle = createParameter(theStorage);
172   aNewArc->endAngle   = createParameter(theStorage);
173   aNewArc->rad        = createParameter(theStorage);
174
175   static std::shared_ptr<GeomAPI_Dir2d> OX(new GeomAPI_Dir2d(1.0, 0.0));
176   std::shared_ptr<GeomAPI_Pnt2d> aCenter(
177       new GeomAPI_Pnt2d(*aNewArc->center.x, *aNewArc->center.y));
178   std::shared_ptr<GeomAPI_Pnt2d> aStart(
179       new GeomAPI_Pnt2d(*aNewArc->start.x, *aNewArc->start.y));
180
181   *aNewArc->rad = aStart->distance(aCenter);
182
183   std::shared_ptr<GeomAPI_Dir2d> aDir(new GeomAPI_Dir2d(aStart->xy()->decreased(aCenter->xy())));
184   *aNewArc->startAngle = OX->angle(aDir);
185
186   aDir = std::shared_ptr<GeomAPI_Dir2d>(
187       new GeomAPI_Dir2d((*aNewArc->end.x) - aCenter->x(), (*aNewArc->end.y) - aCenter->y()));
188   *aNewArc->endAngle = OX->angle(aDir);
189
190   return EntityWrapperPtr(new PlaneGCSSolver_EdgeWrapper(aNewArc));
191 }
192
193 bool isAttributeApplicable(const std::string& theAttrName, const std::string& theOwnerName)
194 {
195   if (theOwnerName == SketchPlugin_Arc::ID()) {
196     return theAttrName == SketchPlugin_Arc::CENTER_ID() ||
197            theAttrName == SketchPlugin_Arc::START_ID() ||
198            theAttrName == SketchPlugin_Arc::END_ID();
199   }
200   else if (theOwnerName == SketchPlugin_Circle::ID()) {
201     return theAttrName == SketchPlugin_Circle::CENTER_ID() ||
202            theAttrName == SketchPlugin_Circle::RADIUS_ID();
203   }
204   else if (theOwnerName == SketchPlugin_Line::ID()) {
205     return theAttrName == SketchPlugin_Line::START_ID() ||
206            theAttrName == SketchPlugin_Line::END_ID();
207   }
208
209   // suppose that all remaining features are points
210   return theAttrName == SketchPlugin_Point::COORD_ID();
211 }