]> SALOME platform Git repositories - modules/shaper.git/blob - src/PartSet/PartSet_FeaturePrs.cpp
Salome HOME
Merge remote-tracking branch 'remotes/origin/master' into SketchSolver
[modules/shaper.git] / src / PartSet / PartSet_FeaturePrs.cpp
1 // File:        PartSet_FeaturePrs.h
2 // Created:     04 Jun 2014
3 // Author:      Natalia ERMOLAEVA
4
5 #include <PartSet_FeaturePrs.h>
6
7 #include <SketchPlugin_Feature.h>
8 #include <SketchPlugin_Sketch.h>
9 #include <SketchPlugin_ConstraintCoincidence.h>
10 #include <SketchPlugin_Line.h>
11 #include <SketchPlugin_Constraint.h>
12
13 #include <GeomDataAPI_Point2D.h>
14
15 #include <ModelAPI_Data.h>
16 #include <ModelAPI_Document.h>
17 #include <ModelAPI_AttributeRefAttr.h>
18 #include <ModelAPI_AttributeRefList.h>
19
20 #include <Precision.hxx>
21
22 using namespace std;
23
24 PartSet_FeaturePrs::PartSet_FeaturePrs(FeaturePtr theFeature)
25 : mySketch(theFeature)
26 {
27 }
28
29 PartSet_FeaturePrs::~PartSet_FeaturePrs()
30 {
31 }
32
33 void PartSet_FeaturePrs::init(FeaturePtr theFeature, FeaturePtr theSourceFeature)
34 {
35   myFeature = theFeature;
36   if (theSourceFeature)
37   {
38     // use the last point of the previous feature as the first of the new one
39     boost::shared_ptr<ModelAPI_Data> aData = theSourceFeature->data();
40     boost::shared_ptr<GeomDataAPI_Point2D> anInitPoint = boost::dynamic_pointer_cast<GeomDataAPI_Point2D>
41                                                                   (aData->attribute(LINE_ATTR_END));
42     setLinePoint(theFeature, anInitPoint->x(), anInitPoint->y(), LINE_ATTR_START);
43     setLinePoint(theFeature, anInitPoint->x(), anInitPoint->y(), LINE_ATTR_END);
44
45     aData = theFeature->data();
46     boost::shared_ptr<GeomDataAPI_Point2D> aPoint = boost::dynamic_pointer_cast<GeomDataAPI_Point2D>
47                                                                  (aData->attribute(LINE_ATTR_START));
48     createConstraint(anInitPoint, aPoint);
49   }
50 }
51
52 boost::shared_ptr<ModelAPI_Document> PartSet_FeaturePrs::document() const
53 {
54   return ModelAPI_PluginManager::get()->rootDocument();
55 }
56
57 FeaturePtr PartSet_FeaturePrs::sketch() const
58 {
59   return mySketch;
60 }
61
62 PartSet_SelectionMode PartSet_FeaturePrs::setPoint(double theX, double theY,
63                                                    const PartSet_SelectionMode& theMode)
64 {
65   PartSet_SelectionMode aMode = theMode;
66   switch (theMode)
67   {
68     case SM_FirstPoint: {
69       setLinePoint(feature(), theX, theY, LINE_ATTR_START);
70       setLinePoint(feature(), theX, theY, LINE_ATTR_END);
71       aMode = SM_SecondPoint;
72     }
73     break;
74     case SM_SecondPoint: {
75       setLinePoint(feature(), theX, theY, LINE_ATTR_END);
76       aMode = SM_DonePoint;
77    }
78     break;
79     default:
80       break;
81   }
82   return aMode;
83 }
84
85 FeaturePtr PartSet_FeaturePrs::feature() const
86 {
87   return myFeature;
88 }
89
90 void PartSet_FeaturePrs::createConstraint(boost::shared_ptr<GeomDataAPI_Point2D> thePoint1,
91                                           boost::shared_ptr<GeomDataAPI_Point2D> thePoint2)
92 {
93   boost::shared_ptr<ModelAPI_Document> aDoc = document();
94   FeaturePtr aFeature = aDoc->addFeature(SKETCH_CONSTRAINT_COINCIDENCE_KIND);
95
96   if (sketch()) {
97     boost::shared_ptr<SketchPlugin_Feature> aSketch = 
98                            boost::dynamic_pointer_cast<SketchPlugin_Feature>(sketch());
99     aSketch->addSub(aFeature);
100   }
101
102   boost::shared_ptr<ModelAPI_Data> aData = aFeature->data();
103
104   boost::shared_ptr<ModelAPI_AttributeRefAttr> aRef1 =
105         boost::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(aData->attribute(CONSTRAINT_ATTR_ENTITY_A));
106   aRef1->setAttr(thePoint1);
107
108   boost::shared_ptr<ModelAPI_AttributeRefAttr> aRef2 =
109         boost::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(aData->attribute(CONSTRAINT_ATTR_ENTITY_B));
110   aRef2->setAttr(thePoint2);
111
112   if (aFeature) // TODO: generate an error if feature was not created
113     aFeature->execute();
114 }
115
116 void PartSet_FeaturePrs::setConstraints(double theX, double theY,
117                                         const PartSet_SelectionMode& theMode)
118 {
119   std::string aPointArg;
120   switch (theMode)
121   {
122     case SM_FirstPoint:
123       aPointArg = LINE_ATTR_START;
124       break;
125     case SM_SecondPoint:
126       aPointArg = LINE_ATTR_END;
127       break;
128     default:
129       break;
130   }
131
132   FeaturePtr aSkFeature = feature();
133
134   boost::shared_ptr<ModelAPI_Data> aData = feature()->data();
135   boost::shared_ptr<GeomDataAPI_Point2D> aPoint = boost::dynamic_pointer_cast<GeomDataAPI_Point2D>
136                                                               (aData->attribute(aPointArg));
137   aData = sketch()->data();
138   boost::shared_ptr<ModelAPI_AttributeRefList> aRefList =
139         boost::dynamic_pointer_cast<ModelAPI_AttributeRefList>(aData->attribute(SKETCH_ATTR_FEATURES));
140
141   std::list<FeaturePtr > aFeatures = aRefList->list();
142   std::list<FeaturePtr >::const_iterator anIt = aFeatures.begin(),
143                                                                   aLast = aFeatures.end();
144   for (; anIt != aLast; anIt++) {
145     FeaturePtr aFeature = *anIt;
146     boost::shared_ptr<GeomDataAPI_Point2D> aFPoint = findLinePoint(aFeature, theX, theY);
147     if (aFPoint)
148       createConstraint(aFPoint, aPoint);
149   }
150 }
151
152 std::string PartSet_FeaturePrs::getAttribute(const PartSet_SelectionMode& theMode) const
153 {
154   std::string aAttribute;
155   switch (theMode)
156   {
157     case SM_FirstPoint:
158       aAttribute = LINE_ATTR_START;
159     break;
160     case SM_SecondPoint:
161       aAttribute = LINE_ATTR_END;
162     break;
163     default:
164     break;
165   }
166   return aAttribute;
167 }
168
169 PartSet_SelectionMode PartSet_FeaturePrs::getNextMode(const std::string& theAttribute) const
170 {
171   PartSet_SelectionMode aMode;
172
173   if (theAttribute == LINE_ATTR_START)
174     aMode = SM_SecondPoint;
175   else if (theAttribute == LINE_ATTR_END)
176     aMode = SM_DonePoint;
177   return aMode;
178 }
179
180 void PartSet_FeaturePrs::getLinePoint(FeaturePtr theFeature,
181                                                const std::string& theAttribute,
182                                                double& theX, double& theY)
183 {
184   if (!theFeature || theFeature->getKind() != SKETCH_LINE_KIND)
185     return;
186   boost::shared_ptr<ModelAPI_Data> aData = theFeature->data();
187   boost::shared_ptr<GeomDataAPI_Point2D> aPoint =
188         boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(theAttribute));
189   theX = aPoint->x();
190   theY = aPoint->y();
191 }
192
193 boost::shared_ptr<GeomDataAPI_Point2D> PartSet_FeaturePrs::findLinePoint(
194                                                FeaturePtr theFeature,
195                                                double theX, double theY)
196 {
197   boost::shared_ptr<GeomDataAPI_Point2D> aPoint2D;
198   if (!theFeature || theFeature->getKind() != SKETCH_LINE_KIND)
199     return aPoint2D;
200   boost::shared_ptr<ModelAPI_Data> aData = theFeature->data();
201   
202   boost::shared_ptr<GeomDataAPI_Point2D> aPoint =
203         boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(LINE_ATTR_START));
204   if (fabs(aPoint->x() - theX) < Precision::Confusion() && fabs(aPoint->y() - theY) < Precision::Confusion() )
205     aPoint2D = aPoint;
206   else {
207     aPoint = boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(LINE_ATTR_END));
208     if (fabs(aPoint->x() - theX) < Precision::Confusion() && fabs(aPoint->y() - theY) < Precision::Confusion() )
209       aPoint2D = aPoint;
210   }
211   return aPoint2D;
212 }
213
214 void PartSet_FeaturePrs::setLinePoint(FeaturePtr theFeature,
215                                                double theX, double theY,
216                                                const std::string& theAttribute)
217 {
218   if (!theFeature)
219     return;
220   boost::shared_ptr<ModelAPI_Data> aData = theFeature->data();
221   boost::shared_ptr<GeomDataAPI_Point2D> aPoint =
222         boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(theAttribute));
223   aPoint->setValue(theX, theY);
224 }